J'essaye de configurer une API pour mon application Web MVC qui aura beaucoup de routes mais une grande partie de la même partie pour chacune. Fondamentalement, un CRUD pour chaque zone. Je suis également en train de le configurer pour qu'il soit possible de versions. J'ai mis en place deux contrôleurs chacun avec une action simple pour commencer et recevoir un conflit dès le départ. L'erreur que j'obtiens est

Je suis après ces urls

Le MVC vous permettra d'avoir un

Je recherche donc un moyen de nommer inutilement des choses comme contacts_delete et locations_delete produisant des URL comme

Je peux aussi bien faire https://foo.bar/aim/v1/contacts_delete/11111 mais cela me semble tellement insensé. Si le MVC peut le faire, je dois croire qu'il existe un moyen d'y parvenir.

L'erreur que j'obtiens est:

Les routes d'attribut portant le même nom «supprimer» doivent avoir le même modèle:

Action: 'rest.fais.foo.edu.Controllers.aimContactsController.delete (rest.fais.foo.edu)' - Modèle: 'aim / v1 / contacts / delete / {id}'

Action: 'rest.fais.foo.edu.Controllers.aimLocationsController.delete (rest.fais.foo.edu)' - Modèle: 'aim / v1 / locations / delete / {id}'

Pour les contrôleurs que j'ai configurés

[EnableCors("SubDomains")]
[ResponseCache(NoStore = true, Duration = 0)]
[Produces("application/json")]
[Route("aim/v1/contacts/[action]")]
[ProducesResponseType(typeof(errorJson), 500)]
public class aimContactsController : Controller
{
    private readonly IHostingEnvironment _appEnvironment;
    private readonly AimDbContext _aim_context;
    private readonly UserManager<ApplicationUser> _userManager;

    public aimContactsController(IHostingEnvironment appEnvironment,
        AimDbContext aim_context,
        UserManager<ApplicationUser> userManager)
    {
        _appEnvironment = appEnvironment;
        _userManager = userManager;
        _aim_context = aim_context;
    }



    [HttpPost("{id}", Name = "delete")]
    public IActionResult delete(string id)
    {

        return Json(new
        {
            results = "deleted"
        });
    }

}


[EnableCors("SubDomains")]
[ResponseCache(NoStore = true, Duration = 0)]
[Produces("application/json")]
[Route("aim/v1/locations/[action]")]
[ProducesResponseType(typeof(errorJson), 500)]
public class aimLocationsController : Controller
{
    private readonly IHostingEnvironment _appEnvironment;
    private readonly AimDbContext _aim_context;
    private readonly UserManager<ApplicationUser> _userManager;

    public aimLocationsController(IHostingEnvironment appEnvironment,
        AimDbContext aim_context,
        UserManager<ApplicationUser> userManager)
    {
        _appEnvironment = appEnvironment;
        _userManager = userManager;
        _aim_context = aim_context;
    }



    [HttpPost("{id}", Name = "delete")]
    public IActionResult delete(string id)
    {

        return Json(new
        {
            results = "deleted"
        });
    }

}

Pour le Startup.cs , j'ai

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        //RolesData.SeedRoles(app.ApplicationServices).Wait();

        app.UseApplicationInsightsRequestTelemetry();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            //app.UseExceptionHandler("/Home/Error");
        }

        app.UseIdentity();
        app.UseDefaultFiles();
        app.UseStaticFiles();

        //app.UseResponseCompression();

        // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
        app.UseSession();

        // custom Authentication Middleware
        app.UseWhen(x => (x.Request.Path.StartsWithSegments("/aim_write", StringComparison.OrdinalIgnoreCase) || x.Request.Path.StartsWithSegments("/rms", StringComparison.OrdinalIgnoreCase)),
        builder =>
        {
            builder.UseMiddleware<AuthenticationMiddleware>();
        });

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.RoutePrefix = "docs";
            //c.SwaggerEndpoint("/docs/v1/wsu_restful.json", "v1.0.0");swagger
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1.0.0");
        });


        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "javascript",
                template: "javascript/{action}.js",
                defaults: new { controller = "mainline" });
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
            routes.MapRoute(
                name: "AIMApi",
                template: "aim/v1/{action}/{id?}",
                defaults: new { controller = "aim" });
            routes.MapRoute(
                name: "AIMContactsApi",
                template: "aim/v1/contacts/{action}/{id?}",
                defaults: new { controller = "aimContactsController" }
            );
            routes.MapRoute(
                name: "AIMLocationsApi",
                template: "aim/v1/locations/{action}/{id?}",
                defaults: new { controller = "aimLocationsController" }
            );
            routes.MapRoute(
                name: "RMSApi",
                template: "{controller=rms}/v1/{action}/{id?}");
        });
    }
}

Ce que je n'arrive pas à trouver dans Google pour trouver la réponse à ce problème Je veux résoudre le problème immédiat, mais toute suggestion est la bienvenue.

14
jeremy.bass 25 juil. 2017 à 00:28

2 réponses

Meilleure réponse

Vos deux itinéraires portent le même nom, cela ne peut pas fonctionner dans ASP.NET Core MVC.

Je ne parle pas des méthodes de nommage, mais de la dénomination des routes. Vous avez appelé vos deux routes avec le même identifiant Name = "delete" dans l'attribut HttpPost. Les noms de route dans MVC identifient de manière unique un modèle de route.

D'après ce que je peux voir, vous n'avez pas vraiment besoin d'identifier vos itinéraires, mais seulement de distinguer différents URI. Pour cette raison, vous pouvez supprimer librement la propriété Name de l'attribut HttpPost de vos méthodes d'action. Cela devrait être suffisant pour que le routeur ASP.NET Core corresponde à vos méthodes d'action.

Si, au lieu de cela, vous voulez revenir en utilisant uniquement le routage d'attributs, vous feriez mieux de changer votre contrôleur comme suit:

// other code omitted for clarity
[Route("aim/v1/contacts/")]
public class aimContactsController : Controller
{
    [HttpPost("delete/{id}")]
    public IActionResult delete(string id)
    {
        // omitted ...
    }
}
29
Federico Dipuma 25 juil. 2017 à 18:59

Une autre solution possible est:

// other solution
[Route("aim/v1/contacts/[Action]")]
public class aimContactsController : Controller
{
    [HttpPost("{id}")]
    public IActionResult delete(string id)
    {
        // omitted ...
    }
}
0
David García Bodego 14 nov. 2019 à 10:23