MVC: How to manage slahses in URL int the first route parameter

前端 未结 4 1493
忘掉有多难
忘掉有多难 2021-01-12 10:01

I need to map two variables that could contain slashes, to a controller, in my ASP MVC application. Let\'s see this with an example.

4条回答
  •  醉酒成梦
    2021-01-12 10:04

    Looks like a custom route might cut the mustard:

    public class MyRoute: Route
    {
        public MyRoute()
            : base("{*catchall}", new MvcRouteHandler())
        {
        }
    
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            var rd = base.GetRouteData(httpContext);
            if (rd == null)
            {
                // we do not have a match for {*catchall}, although this is very
                // unlikely to ever happen :-)
                return null;
            }
    
            var segments = httpContext.Request.Url.AbsolutePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (segments.Length < 4)
            {
                // we do not have the minimum number of segments
                // in the url to have a match
                return null;
            }
    
            if (!string.Equals("items", segments[1], StringComparison.InvariantCultureIgnoreCase) &&
                !string.Equals("items", segments[2], StringComparison.InvariantCultureIgnoreCase))
            {
                // we couldn't find "items" at the expected position in the url
                return null;
            }
    
            // at this stage we know that we have a match and can start processing
    
            // Feel free to find a faster and more readable split here
            string repository = string.Join("/", segments.TakeWhile(segment => !string.Equals("items", segment, StringComparison.InvariantCultureIgnoreCase)));
            string path = string.Join("/", segments.Reverse().TakeWhile(segment => !string.Equals("items", segment, StringComparison.InvariantCultureIgnoreCase)).Reverse());
    
            rd.Values["controller"] = "items";
            rd.Values["action"] = "index";
            rd.Values["repository"] = repository;
            rd.Values["path"] = path;
            return rd;
        }
    }
    

    which could be registered before the standard routes:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.Add("myRoute", new MyRoute());
    
        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
    }
    

    And if you intend to put arbitrary strings in the path portion of your urls I hope you are aware of the Zombie Operating Systems which might surprise you.

提交回复
热议问题