0

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();
}
Sujit.Warrier
  • 2,815
  • 2
  • 28
  • 47
  • You can only have the last parameter marked `UrlParameter.Optional`. And you refer to 3 parameters `CatId`, `ChildCatId` and `viewtype`) which do not even exist in your route definition –  Sep 18 '17 at 11:01
  • yup changed it. but still how to get the Id properly – Sujit.Warrier Sep 18 '17 at 11:03
  • You need to create separate route definitions (to the same controller) but its not clear what options you want and you have not shown the signature of the method –  Sep 18 '17 at 11:03
  • I baiscally want to ignore everthing after Category/ till the parameters begin. or Just match the Entire url from db get corresponding Ids either works for me – Sujit.Warrier Sep 18 '17 at 11:05
  • Is there some reason that you want the `id` at the end (as opposed to `/category/clothing/128/shirts/formal`? –  Sep 18 '17 at 11:07
  • Well the thing the original application is in webforms. there Url rewrite module has been used along with a db provider. so baiscally each time a url like 'category/clothing' is matched in the db to corresponding url like 'Category.aspx?Id=1256' and it is routed to that page. I want to keep the urls as close as possible to the original application. – Sujit.Warrier Sep 18 '17 at 11:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154676/discussion-between-stephen-muecke-and-sujit-warrier). –  Sep 18 '17 at 11:13

1 Answers1

0

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();
}
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • This worked too. but the answer provided here https://stackoverflow.com/questions/31934144/multiple-levels-in-mvc-custom-routing worked better – Sujit.Warrier Sep 19 '17 at 11:44