Routing Reserved Words in ASP.Net

前端 未结 2 1528
一个人的身影
一个人的身影 2020-12-12 02:23

I have a legacy url that I wish to map to a route in my ASP.Net MVC application

e.g. http://my.domain.com/article/?action=detail&item=22
<
相关标签:
2条回答
  • 2020-12-12 03:02

    controller,action and area are the only reserved words in asp.net MVC. "Reserved" means that MVC gives special meaning to them, especially for Routing.

    There are also others words (COM1-9, LPT1-9, AUX, PRT, NUL, CON), not specific to asp.net, than can not be in the url. This is explained why here and how to by-pass here.

    Edit : There are no ways to use them because asp.net mvc relies on them in route data.

    Here is an decompiled example taken from UrlHelper :

    // System.Web.Mvc.RouteValuesHelpers
    public static RouteValueDictionary MergeRouteValues(string actionName, string controllerName, RouteValueDictionary implicitRouteValues, RouteValueDictionary routeValues, bool includeImplicitMvcValues)
    {
        RouteValueDictionary routeValueDictionary = new RouteValueDictionary();
        if (includeImplicitMvcValues)
        {
            object value;
            if (implicitRouteValues != null && implicitRouteValues.TryGetValue("action", out value))
            {
                routeValueDictionary["action"] = value;
            }
            if (implicitRouteValues != null && implicitRouteValues.TryGetValue("controller", out value))
            {
                routeValueDictionary["controller"] = value;
            }
        }
        if (routeValues != null)
        {
            foreach (KeyValuePair<string, object> current in RouteValuesHelpers.GetRouteValues(routeValues))
            {
                routeValueDictionary[current.Key] = current.Value;
            }
        }
        if (actionName != null)
        {
            routeValueDictionary["action"] = actionName;
        }
        if (controllerName != null)
        {
            routeValueDictionary["controller"] = controllerName;
        }
        return routeValueDictionary;
    }
    
    0 讨论(0)
  • 2020-12-12 03:09

    I have managed to crack it using a custom ModelBinder. I create a basic class called QueryString

        public class QueryString
        {
                private readonly IDictionary<string,string> _pairs;
    
                public QueryString()
                {
                        _pairs = new Dictionary<string, string>();
                }
    
                public void Add(string key, string value)
                {
                        _pairs.Add(key.ToUpper(), value);
                }
    
                public string Get(string key)
                {
                        return _pairs[key.ToUpper()];
                }
    
                public bool Contains(string key)
                {
                        return _pairs.ContainsKey(key.ToUpper());
                }
        }
    

    Then I create my custom binder for that:-

        public class QueryStringModelBinder : IModelBinder
        {
                public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
                {
                        var queryString = new QueryString();
                        var keys = controllerContext.HttpContext.Request.QueryString.AllKeys;
    
                        foreach (var key in keys)
                        {
                                queryString.Add(key, controllerContext.HttpContext.Request.QueryString[key]);
                        }
    
                        return queryString;
                }
        }
    

    In my Global.asax I register it:-

    ModelBinders.Binders.Add(typeof(QueryString), new QueryStringModelBinder());
    

    Now I can use that in my RedirectController:-

    public RedirectToRouteResult Item(QueryString queryString)
    {
        // user QueryString object to get what I need
        // e.g. queryString.Get("action");
    }
    
    0 讨论(0)
提交回复
热议问题