jsmith
jsmith

Reputation: 43

Hyphenated Friendly URL Routing

I'm using ASP.Net MVC Core 2.0 and having a hard time getting routing working for hyphenated friendly URLs. I would like the following URL style:

admin is the area:
    /admin/invoice-categories/new    - Creates a new invoice category
    /admin/invoice-categories/edit/1 - Edits a invoice category
    /admin/invoice-categories        - Shows the invoice categories list

This is my controller code:

[Area("admin")]
[Route("[area]/invoice-categories/"]
class InvoiceCategoriesController {
   public IActionResult New() {}
   public IActionResult Edit(int id) {}
   public IActionResult Index() {}
}

However, this results in an exception stating the "New, Edit, Index" methods in the controller are ambiguous.

Is there a way to get it to work WITHOUT using defining the action name specifically (like HttpGet("New"))?

Upvotes: 4

Views: 1525

Answers (2)

Chris Pratt
Chris Pratt

Reputation: 239240

Attribute routing is an all or nothing affair, at least in the context of a single controller (you can use attribute routing on some controllers and not others). The point is that once you specify a route on your controller, all actions either need a route specified as well, or they will default to "", or the exact route of the controller itself.

In other words, your Index action is fine as-is, but to remove the disambiguation, you'd need to specific Route, HttpGet, HttpPost, etc. on your other actions.

Upvotes: 3

DavidG
DavidG

Reputation: 118937

Unfortunately there isn't a concept of default action in MVC Core attribute routing. Your alternatives are:

  1. Create the route in the middleware where it is possible to specify a default action:

    routes.MapRoute(
        name: "invoice-categories",
        template: "{area}/invoice-categories/{action=Index}/{id?}",
        defaults: new { area = "admin", controller = "InvoiceCategories" });
    
  2. Add an extra route on your Index action:

    [Area("admin")]
    [Route("[area]/invoice-categories/[action]"]
    class InvoiceCategoriesController {
        public IActionResult New() {}
        public IActionResult Edit(int id) {}
    
        [Route("[area]/invoice-categories"]
        public IActionResult Index() {}
    }
    

Upvotes: 4

Related Questions