13

以下の URL を使用して MVC サイトを実装する必要があります。

  • カテゴリ1/製品/1/ウィキ
  • カテゴリ1/製品/2/ウィキ
  • カテゴリ1/サブカテゴリ2/製品/3/ウィキ
  • カテゴリ1/サブカテゴリ2/サブカテゴリ3/製品/4/wiki
  • などなど

一致基準は、URL が「wiki」で終わることです。

残念ながら、以下のキャッチオールは URL の最後の部分でのみ機能します。

routes.MapRoute("page1", // Route name
                "{*path}/wiki", // URL with parameters
                new { controller = "Wiki", action = "page", version = "" } // Parameter defaults

MVC の拡張性オプションを検討する時間がなかったので、これを実装するためにどのような選択肢があるのか​​疑問に思っていました。サンプル/例はどれも素晴らしいでしょう!

4

1 に答える 1

15

前述のように、catch-allパラメーターはルートの最後にのみ表示されます。投稿したコードは実行時エラーをスローし、アプリケーションを実行しようとしても死の黄色い画面を表示します。

カスタムルーティングシナリオを構築するためのいくつかの拡張ポイントがあります。これらは、Route、RouteBase、およびIRouteHandlerです。

RouteBaseを拡張することにより、処理するルートの生成リストを作成できます。通常は、リソース(コントローラー名)を取り込むコンストラクターを作成し、そのコンストラクターが担当するルートのリストを割り当てて、それをglobal.asaxにマッピングするというパターンに従います。ビルドできるサンプルコードは次のとおりです。

public class MyRoute : RouteBase
{
    private List<Route> _routes = new List<Route>();

    public MyRoute(string resource)
    {
        // make a Resource property, not shown in this example
        this.Resource = resource;

        // Generate all your routes here
        _routes.Add(
            new Route("some/url/{param1}",
            new McvRouteHandler {
                Defaults = new RouteValueDictionary(new {
                    controller = resource,
                    action = actionName
                }),
            Constraints = new RouteValueDictionary()
        );
        _routes.Add(...); // another new route   
    }

    public override RouteData GetRouteData(HttpContextBase context)
    {
        foreach (var route in _routes)
        {
            var data = route.GetRouteData(context);
            if (data != null)
            { 
                return data;
            }
        }
        return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary rvd)
    {
        foreach (var route in _routes)
        {
            var path = route.GetVirtualPath(context, rvd);
            if (path != null)
            { 
                return path;
            }
        }
        return null;
    }
}

ルーティングクラスを使用するにroutes.Add(new MyRoute("page1"));は、Global.asaxでaを実行します。

さらに詳細な制御が必要な場合は、IRouteHandlerを実装できます。上記の例に示すように、ルートにMvcRouteHandlers()を作成する代わりに、独自のIRouteHandlerを使用してください。これにより、リクエストデータからコントローラーを選択するロジックをオーバーライドできます。

フレームワーク全体は非常に拡張可能ですが、それを適切に行うにはかなりのことを学ぶ必要があります。可能であれば、キャッチオールパラメータを利用するために、可能であればURLを再配置することをお勧めします。

于 2009-07-10T04:32:27.207 に答える