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

前端 未结 2 379
轮回少年
轮回少年 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:00

    This looks like a dupe of ASP.NET routing: Literal sub-segment between tokens, and route values with a character from the literal sub-segment which is a much simpler version of the bug. I'd recommend closing this one in favor of that one.

    I answered that question.

    0 讨论(0)
  • 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<string, IRouteRule>();
            foreach (var pair in new RouteValueDictionary(rules))
                Rules.Add(pair.Key, (IRouteRule)pair.Value);
        }
    
        public Dictionary<string, IRouteRule> 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-") }));
    
    0 讨论(0)
提交回复
热议问题