Failing ASP.NET MVC route. Is this a bug or corner case?

前端 未结 2 381
轮回少年
轮回少年 2021-02-01 08:22

I have an ASP.NET MVC 3 application where users can post suggestions along the lines of \"bla bla would be better if yada yada yada\". For the suggestion detail page I

2条回答
  •  佛祖请我去吃肉
    2021-02-01 09:12

    I'm not sure why it behaves this way, but you can use something like this:

    public interface IRouteRule
    {
        object ProcessIncoming(object value);
        object ProcessOutgoing(object value);
    }
    
    public class StartsWithRouteRule : IRouteRule
    {
        public StartsWithRouteRule(string value)
        {
            Value = value;
        }
    
        public string Value { get; protected set; }
    
        public object ProcessIncoming(object value)
        {
            var result = value as string;
            if (result == null)
                return null;
    
            if (!result.StartsWith(Value))
                return null;
    
            return result.Substring(Value.Length);
        }
    
        public object ProcessOutgoing(object value)
        {
            var result = value as string;
            if (result == null)
                return null;
    
            return Value + result;
        }
    }
    
    public class ComplexRoute : Route
    {
        public ComplexRoute(string url, object defaults, object rules)
            : this(url, new RouteValueDictionary(defaults), rules)
        { }
        public ComplexRoute(string url, RouteValueDictionary defaults, object rules)
            : base(url, defaults, new MvcRouteHandler())
        {
            Rules = new Dictionary();
            foreach (var pair in new RouteValueDictionary(rules))
                Rules.Add(pair.Key, (IRouteRule)pair.Value);
        }
    
        public Dictionary Rules { get; protected set; }
    
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            var result = base.GetRouteData(httpContext);
    
            if (result == null)
                return null;
    
            foreach (var pair in Rules)
            {
                var currentValue = result.Values[pair.Key];
                if (currentValue == null)
                    return null;
    
                var value = pair.Value.ProcessIncoming(currentValue);
                if (value == null)
                    return null;
    
                result.Values[pair.Key] = value;
            }
    
            return result;
        }
    
        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            values = new RouteValueDictionary(values);
    
            foreach (var pair in Rules)
            {
                var currentValue = values[pair.Key];
                if (currentValue == null)
                    return null;
    
                var value = pair.Value.ProcessOutgoing(currentValue);
                if (value == null)
                    return null;
    
                values[pair.Key] = value;
            }
    
            return base.GetVirtualPath(requestContext, values);
        }
    }
    

    Usage:

    routes.Add(new ComplexRoute(
        "suggestion/{id}/{it}/{if}",
        new { controller = "suggestion", action = "details" },
        new { @if = new StartsWithRouteRule("would-be-better-if-") }));
    

提交回复
热议问题