Search code examples
c#asp.net-mvc-5asp.net-mvc-routing

Multiple Parameters MVC routing


I am making a library-like website. In this library an article can have a category, and said category can have up to 2 parent categories, like: "World > Country > City".

I want to keep all the displaying of views to a single Controller for all articles, named LibraryController. And the 2 actions being used are Article(string id) and Category(string[] ids)

To view an article called "The Templar Order" the user must input: /library/article/the-templar-order

Alright, so now the categories. I have 2 approaches in my head, this example is to view the "City" category:

  1. The simple approach: /library/world-country-city
  2. The one I would like: /library/world/country/city
  3. The one I do NOT want, as it becomes too clumsy: /library/category/world/country/city

But I am a bit confused as to how I would go about creating a route that takes 3 parameters and essentially no action. And except for the first parameter "world" the rest should be optional, like this: "/library/world/" > "/library/world/country/" > "/library/world/country/city/"

So how would I go about creating such a route ?

Solution

RouteConfig.cs

// GET library/article/{string id}
routes.MapRoute(
    name: "Articles",
    url: "Library/Article/{id}",
    defaults: new { controller = "Library", action = "Article", id = "" }
    );

// GET library/
routes.MapRoute(
    name: "LibraryIndex",
    url: "Library/",
    defaults: new { controller = "Library", action = "Index" }
    );

// GET library/category/category/category etc.
routes.MapRoute(
    name: "Category",
    url: "Library/{*categories}",
    defaults: new { controller = "Library", action = "Category" }
    );

Solution

  • You can achieve that with the following two routes.

    // GET library/article/the-templar-order
    routes.MapRoute(
         name: "Articles",
         url: "Library/Article/{id}",
         defaults: new { controller = "Library", action = "Article" }
     );
    
    // GET library/world/country/city
    routes.MapRoute(
         name: "Category",
         url: "Library/{*categories}",
         defaults: new { controller = "Library", action = "Category" }
     );
    

    And a slight modification to the target action

    public ActionResult Category(string categories) {
        categories = categories ?? string.Empty;
        var ids = categories.Split(new []{'/'}, StringSplitOptions.RemoveEmptyEntries);
        //...other code
    }