13

私はASP.NETMVC3アプリケーションを持っており、ユーザーは「やだやだやだならblablaの方がいい」という方針に沿って提案を投稿できます。提案の詳細ページでは、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

PhilHaackのRoutingDebuggerを試し、ルートが実際にまで機能することを確認したsuggestion/84/this-site/would-be-better-if-would-be-better-if-ので、2番目の「would-be-better-if」が実際に受け入れられます。その後に何かを追加すると、実際にはURLがどのルートとも一致しなくなります(Omarに感謝します-コメントを参照してください-ヘルプが必要です)


ルート定義は、SEOの観点から、このケースで管理できる限り良いと思うので、実際には変更したくないことを覚えておいてください。

では、どうしてルートの固定部分に等しいテキストがあると、リンクがルートと一致しなくなるのでしょうか。なぜルートが壊れているのですか?

理由を理解することで解決策が得られるか、少なくとも興味深い問題を適切に理解できると信じているので、私は実際にはその理由にもっと興味を持っています。

4

2 に答える 2

5

なぜこのように動作するのかはわかりませんが、次のようなものを使用できます。

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-") }));
于 2011-03-12T09:59:02.050 に答える
2

これは、ASP.NET ルーティングの複製のように見えます: トークン間のリテラル サブセグメント、およびリテラル サブセグメントからの文字を使用したルート値は、バグのより単純なバージョンです。あれを優先して、これを閉じることをお勧めします。

私はその質問に答えました。

于 2011-09-19T05:31:50.653 に答える