ASP.NET MVC 5 - Mapping controller route and proper way to map nested actions

58 Views Asked by At

I have a controller called Expense that has the usual (default template generated) actions:

  • Expense/Index
  • Expense/Create/{id}
  • Expense/Details/{id}
  • Expense/Edit/{id}

I also have a controller called Expense_Status, whose actions (from default template with the addition of the string serialNumber and Date month parameters) are mapped to:

  • Expense/{serialNumber}/Status/{action}/{month}, e.g. Expense/123/Status/Edit/11-2020

My App_Start/ RouteConfig.cs is as following:

    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.Ignore(url: "Expense_Status{pathInfo}", constraints: new { pathInfo = "."});

            routes.MapMvcAttributeRoutes();

            routes.MapRoute(
                name: "ExpenseStatus",
                url: "Expense/{serialNumber}/Status/{action}/{month}",
                defaults: new { controller = "Expense_Status", action = "Index", month = UrlParameter.Optional }
                );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

What I would like to know is:

  1. How can I remove/ignore the path Expense_Status/{action}/{id} that matches the 'default' mapping, and keep only Expense/123/Status/Edit/11-2020 and similar paths?

  2. Is this the proper way to map this kind of Objects since Expense has multiple Statuses? I saw this post MVC Hierarchical Routing , I like that I can have the Expense_Status actions in the Expense controller, but do not like the fact that I have to 'hardcode' all the actions as separate route mapping in the RouteConfig.cs

I have tried adding the following to the RouteConfig.cs but did not solve question 1) :

routes.Ignore(url: "Expense_Status{pathInfo}", constraints: new { pathInfo = "."});

Expense_Status/etc.... is still accessible


Tried using the solution from this post Exclude a Controller from Default Route C# MVC , but how can I exclude multiple controllers without writing multiple MapRoute -ings for each controller that I would like to exclude?

e.g.

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                constraints: new NotEquals("Expense_Status")
            );

routes.MapRoute(
                name: "AnotherDefault",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                constraints: new NotEquals("<name_of_other_controller_to_exclude>")
            );

It seems like there is too much repetition and code pollution.

EDIT 1: There is also the option of using Attribute Routing like so:

public class ExpenseController : Controller
{
    // eg: /Expense/123/Status/Edit/11-2020
    [Route(“Expense/{serialNumber}/Status/Edit/{month}”)]
    public ActionResult StatusEdit(string serialNumber, string month)
    {
        ...
    }
}

, but I do not like the fact that I have to specify the name of the controller in the route.

0

There are 0 best solutions below