3

デフォルトのルートから継承して、独自のルート クラスを実装しようとしています。

これは私のカスタムルートクラスがどのように見えるかです:

public class FriendlyRoute : Route
{
    public FriendlyRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
        : base(url, defaults, routeHandler)
    {

    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);

        var controllerName = routeData.Values["controller"].ToString();
        var actionName = routeData.Values["action"].ToString();

        routeData.Values["controller"] = fix(controllerName);
        routeData.Values["action"] = fix(actionName);

        return routeData;
    }

    private string fix(string name)
    {
        //Remove dashes: "my-controller" => "mycontroller"
    }
}

私がやっているのは、ダッシュ付きの URL を受け入れ、正しいアクション (「my-controller/my-action」から「MyController/MyAction」へ) にルーティングすることですが、このカスタム ルートへの追加の計画がいくつかあります。

カスタム ルート クラスを実行するには、次のルート構成を使用します。

routes.Add("Default",
           new FriendlyRoute("{controller}/{action}/{id}",
                             new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }),
                             new MvcRouteHandler()));

これはうまくいきます!しかし、私は URL 構造に満足していません。コントローラー名のないアクション名のみの URL (「/about」、「/contact」など) と、コントローラー名付きの URL (「/mypage」、「/mypage/invoices」など) が必要です。デフォルトのルート クラス (独自のカスタムではない) を使用して開始し、この問題を修正します。

routes.Add("MyPages",
           new Route("MyPage/{action}",
                     new RouteValueDictionary(new { controller = "MyPage", action = "Summary"}),
                     new MvcRouteHandler()));

routes.Add("Public",
           new Route("{action}/{id}",
                     new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }),
                     new MvcRouteHandler()));

これも問題なく動作しますが、ダッシュを含む URL はサポートされなくなりました。そのため、カスタム ルート クラスをルート構成にスワップするだけです。

routes.Add("MyPages",
           new FriendlyRoute("MyPage/{action}",
                             new RouteValueDictionary(new { controller = "MyPage", action = "Summary" }),
                             new MvcRouteHandler()));

routes.Add("Public",
           new FriendlyRoute("{action}/{id}",
                             new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }),
                             new MvcRouteHandler()));

アプリケーションを実行すると、デフォルト ページ ("/") に移動しようとすると、FriendlyRoute.GetRouteData() で base.GetRouteData(httpContext) を呼び出すと null が返されるため、アプリケーションがクラッシュします。

カスタムルートクラスを作成するのは初めてなので、何が間違っているかについてのヒントをいただければ幸いです。

4

1 に答える 1

2

追加の 2 つのルートを追加した後、ルート URL がヒット (「/」) すると、ルート定義に対して、一致するまで上から下に順番に処理されます。したがって、最初のルート"MyPage/{action}"ではメソッドが呼び出さpublic abstract RouteData GetRouteData(HttpContextBase httpContext);れ、URL がルート定義と一致し、制約がチェックされます。RouteValueDictionary一致チェックと制約チェックの場合はオブジェクトを返し、それ以外の場合はオブジェクトを返しますnull。したがって、最初のルート定義では、URL が一致しないため、null が返されます。愚か者としてnullチェックを追加する必要があります

if (routeData != null)
{
    var controllerName = routeData.Values["controller"].ToString();
    var actionName = routeData.Values["action"].ToString();

    routeData.Values["controller"] = Fix(controllerName);
    routeData.Values["action"] = Fix(actionName);
}

関連リソース: Route.cs

お役に立てれば。

于 2013-04-22T18:49:21.300 に答える