Search code examples
asp.netasp.net-mvcasp.net-mvc-4routeconfig

Route Config for dynamic urls


So Im working on an MVC 4 application. My problem is for a certain controller the Url can be http://domain/category/clothing/1256 or it can be http://domain/category/clothing/shirts/formal/128'. As you can see the depth of the url changes but all must route to the category controller.

Since the max dept of the url is not known, I cant User Routeconfig as I dont know when the parameters will come.

routes.MapRoute(
    name: "Category",
    url: "Category/{ignore}/{id}/{SubCatId}/{SubSubCatId}",
    defaults: new { controller = "Category", action = "Index", CatId = UrlParameter.Optional, SubCatId = UrlParameter.Optional, SubSubCatId = UrlParameter.Optional },
    namespaces: new[] { "CSPL.B2C.Web.Controllers" },
    constraints: new { id = @"\d+" }
);

The above code will not work as it accounts for only one level. Any ideas on how to achieve this

The Index method of category controller

public ActionResult Index(string id, string SubCatId, string SubSubCatId)
{
    return view();
}

Solution

  • Your only option is a catch-all param. However, there's two caveats with that:

    1. The catch-all param must be the last part of the route
    2. The catch-all param will swallow everything, including /, so you'll have to manually parse out individual bits you need with a regular expression or something.

    Essentially, you'll just change the route to:

    routes.MapRoute(
        name: "Category",
        url: "Category/{*path}",
        defaults: new { controller = "Category", action = "Index" },
        namespaces: new[] { "CSPL.B2C.Web.Controllers" }
    );
    

    Then, your action would need to be changed to accept this new param:

    public ActionResult Index(string path)
    {
        // parse path to get the data you need:
    
        return view();
    }