4

いくつかの領域(基本グリッドマスター/詳細タイプシステム)を備えたアプリケーションの作業を始めたばかりです。MVC(特に4)の優れたルーティング機能を利用することを検討していますが、「うまくいきません」。私は推測します。

現在定義されている唯一のルートは基本ルートです。

routes.MapRoute("Default", 
            "{controller}/{action}/{id}", 
            new { controller = "Account", action = "Index", id = UrlParameter.Optional }
        );

これは問題ありません。定義したエリアで機能するので、ユーザーがどこにいるかを認識し、ユーザーがいる場所/エリアに応じて適切なコントローラーにルーティングする必要があると思います。

今、私は処理できる新しいルートを設定しようとしています

/someController/someAction/{statusName} 

具体的には次のようなものです。

/OrderManager/List/New 

/OrderManager/List/Viewed

ここで、「新規」は「新規」ステータスであり、アクションシグネチャは次のようになります。

public ActionResult List(string statusName)

Idの代わりに「statusName」を識別するデフォルトのルートの下に新しいルートを追加できると想定していましたが、もちろん、Hはルーティングメカニズムが次の違いをどのように認識するのでしょうか。

/ controller1 / action1 / 15

/ controller2 / action2 / new

次の形式で「静的」ルートを追加してみました

routes.MapRoute("Default", 
            "ControllerName/ControllerAction/{statusName}", 
            new { statusName = UrlParameter.Optional }
        );

その1つのルートだけを「ハイジャック」して、それを使って何か特別なことをすることができると思いましたが、役に立つことを知るために、ルーターは最初の試合で停止しますか?とにかく、それがこの問題に対処するための間違った方法だったと思います。

だから今、私は次のようなものに到達するというアイデアを経験しています:

/somecustomroutename/somesortValue

元。/ OrderManagerList / viewNew

これらのルートは基本的に「エイリアス」になります。次のルートを追加するとうまくいくと思っていました。

 routes.MapRoute("Default_List",
          "OrderManagerList/{statusName}",
          new {controller="OrderManager", action="List", statusName= UrlParameter.Optional }
      );

OrderManagerコントローラーの関連アクション:

public ActionResult List(string statusName)

何をしようとしても、引数がnullであるか、「リソースが見つかりません」

コントローラに対応するビューファイルが必要であることはわかっていますが、ここでは問題ではありません。問題は、ルーティングを理解しようとする試みです。

だから私の質問..基本的に、MVC(4)のルーティングについて何が欠けていますか?私のような単純な人が理解するためのいくつかの良い記事でさえ?

私の理解; ルートを定義し、それを「エンドポイント」にマッピングします。ただし、マシンが行っている仮定を理解していないと思います。

とにかく、さらに説明/編集が必要な場合はお知らせください。

前もって感謝します。

4

1 に答える 1

10

ルートの基本原則は、ルートが上から下に評価されることであり、ルーティングシステムは、最適な一致ではなく、最初の一致を使用します。

これは、最も具体的なルートを最初に、最も一般的なルートを最後に、特定の順序でルートを並べ替える必要があることを意味します。

この原則を念頭に置いて、あなたの状況を見てみましょう。最初は、デフォルトルートのみが定義されています。

routes.MapRoute("Default", 
        "{controller}/{action}/{id}", 
        new { controller = "Account", action = "Index", id = UrlParameter.Optional }
    );

URLパターンは「{controller}/{action}/{id}」です。それ自体では、これは3セグメントのURLと一致し、3セグメント未満のURLとは一致しません。ただし、3番目の入力パラメーターはデフォルトパラメーターであり、1番目と2番目のセグメントのデフォルトを定義し、3番目のセグメントがオプションであることを示します。これの次の効果は、ルートを0、1、2、または3つのセグメントを持つURLと一致させることです。

次に、3番目のURLセグメントが「statusName」パラメーターにマップされ、次のようなURLを処理できるルートを追加します。

OrderManager/List/New 
OrderManager/List/Viewed 

ここで取ることができる2つの基本的なアプローチがあります。1)これらの2つのURLのみを処理する非常に具体的なルートを作成するか、2)一般的なケースを処理するためのより一般的なルートを作成してみることができます。最初に最初のケースを見てみましょう。次のようにルートを作成できます。

routes.MapRoute("", "OrderManager/List/{statusName}",
              new { Controller = "OrderManager", Action = "List" });

このルートはデフォルトルートよりも具体的であるため、このルートをデフォルトルートの前に配置する必要があることに注意してください。

より一般的なルートが必要な場合は、このルートがデフォルトルートとどのように異なるかを決定する必要があります。どちらも3つのセグメントを持つURLと一致するためです。新しいルートが3番目のセグメントに文字のみを含むものをすべて受け入れ、デフォルトルートを残して数字を含むものを処理するとします。これは、ルート制約を使用して行うことができます。たとえば、次のようにルートを記述できます。

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            constraints: new { id = @"^\d+$" });

        routes.MapRoute(
            name: "NewRoute",
            url: "{controller}/{action}/{statusName}",
            defaults: new { Controller = "OrderManager", Action = "List" },
            constraints: new { statusName = "^[A-Za-z]+$" });

これらの2つのルートでは、3番目のセグメントに文字のみが含まれる3セグメントのURLは、3番目のセグメントを「statusName」という変数に入れますが、3番目のセグメントに整数があるURLは、3番目のセグメントを「 id」。

実際に複雑なアプリケーションでは、ルートが複雑になる可能性があります。ルートを追加または変更するときに問題が発生しないように、ルートの単体テストを作成すると非常に有利です。

ルーティングに関する適切なリファレンスについては、Scott Sandersonの本を参照するか、MSDNのドキュメントを参照してください。

于 2013-01-29T17:40:48.577 に答える