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

谁都会走 提交于 2019-12-02 18:25:41
Haacked

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.

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-") }));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!