asp.net-mvcasp.net-mvc-5mvcroutehandler

ASP.NET MVC 5: single controller method to handle paths in file browser mode


I want to have some controller with the single method that would allow me to navigate through some hierarchy (file system etc.).

In other words I want to have possibility to access this method with flexible routes and get part of routes as parameter. For example in case of this hierarchy

Root
  Sub-folder-A
  Sub-folder-B
    Sub-folder-C

I want to have access folders with the next routes

mymvcapplication/explorer/root
mymvcapplication/explorer/root/sub-folder-a
mymvcapplication/explorer/root/sub-folder-b/sub-folder-c

What and where should I configure to implement it properly?


Solution

  • To support variable number of url parameter values in the request url, you can mark your method parameter with * prefix in the route definition.

    With MVC Attribute routing,

    [Route("explorer/root/{*levels}")]
    public ActionResult Details(string levels = "")
    {
        if (String.IsNullOrEmpty(levels))
        {
            //request for root
        }
        else
        {
            var levelArray = levels.Split('/');
            //check level array and decide what to do 
        }
        return Content("Make sure to return something valid :) ");
    }
    

    The last parameter prefixed with * is like a catch-all parameter which will store anything in the url after explorer/root

    So when you request yoursite.com/explorer/root/a/b/c/d , the default model binder will map the value "a/b/c/d" to the levels parameter. You can call the Split method on that string to get an array of url segments.

    To enable attribute routing, go to RouteConfig.cs and call the MapMvcAttributeRoutes() method in the RegisterRoutes.

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapMvcAttributeRoutes();
    
        routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  
        );
    }