繁体   English   中英

ASP.NET MVC路由失败。 这是一个错误或角落案件吗?

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

我有一个ASP.NET MVC 3应用程序,用户可以发布建议, 如果如果 yada yada yada,bla bla 会更好 ”。 对于建议详细信息页面,我已经定义了一个很好的SEO友好路线如下:

routes.MapRoute(null, "suggestion/{id}/{it}/would-be-better-if-{if}", 
    new { controller = "suggestion", action = "details" });

正如你所看到的,我希望修复“将会更好”。

此路线适用于任何旧建议,并生成链接,如suggestion/5/this-site/would-be-better-if-it-had-a-iphone-application ,并点击链接实际上请求相应的详细信息页面。

我的一个朋友,具有讽刺意味的恰好是测试人员,已经设法,不由自主地发布了一条实际上打破了这条路线的建议:“ 如果'总是在中间对齐,那么这个网站会更好 ”。
为这个建议生成的链接是/suggestion/84/this-site/would-be-better-if-would-be-better-if-was-always-alligned-in-the-middle

我已经尝试了Phil Haack的路由调试器 ,并确认该路由实际上会工作,直到suggestion/84/this-site/would-be-better-if-would-be-better-if- ,所以第二个“将是 - 更好 - 如果“实际上被接受; 之后添加任何内容实际上会导致网址不匹配任何路由(感谢Omar -see评论 - 寻求帮助)


请记住, 我真的不想改变路线定义,因为我认为这对于这个案例来说是一样好,SEO-wise。

那么, 如何让文本等于路由的固定部分会阻止链接匹配路由? 路线为何破裂?

我实际上对这个为什么更感兴趣,因为我相信理解为什么会导致解决方案或至少正确理解一个相当有趣的问题。

我不确定它为什么会这样,但你可以使用这样的东西:

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);
    }
}

用法:

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

这看起来像是一个ASP.NET路由的欺骗:令牌之间的文字子段,以及带有来自文字子段的字符的路由值,这是一个更简单的bug版本。 我建议关闭这一个以支持那个。

我回答了这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM