11

ASP MVC ルートをテストしていますASP MVC 5.1 の属性ルートに問題があります

次のようなコントローラーがある場合:

public class FooController : Controller
{
    [Route("foo")]
    [HttpGet]
    public ActionResult Get()
    {
      .... 
    }

    [Route("foo")]
    [HttpPost]
    public ActionResult Post()
    {
      .... 
    }
}

次に、特定のリクエストに一致するルートをテストするために、 を呼び出しますroutes.GetRouteDataSystem.Web.Routing.RouteDataルートと、一致するコントローラーとアクションを示す値を含むを取得します。

問題は、このルートがRouteCollectionRouteのインスタンスになり 、この内部クラスがこれら 2 つのアクションへのルート グループのラッパーになっていることです。コントローラは にありますRouteData.valuesが、アクションはありません。これらの含まれているルートは で取得できますrouteData.Values["MS_DirectRouteMatches"] as IList<RouteData>

上記の例では、2 つのアクション メソッドに対して、リストに 2 つのルートがあります。一致したルートのアクション メソッド名を読み取ることができるように、含まれているルートのどれが実際に一致するかを知る必要があります。このルートを解決するにはどうすればよいですか?

まったくないというデザインの選択に少し困惑していRouteCollectionRouteます。ルーティング時には、ルート コレクションがあり、次に を呼び出して URL のルートを解決しますGetRouteData。これでルートは 1 つになりました。しかし、そうであれば、それRouteCollectionRouteまだルートのコレクションであり、ルートの解決はまだ終わっていません。RouteCollectionRoute を持つことで何が得られますか? ルート解決は 2 段階のプロセスになりましたか? それとも再帰的なプロセスですか?

ASP MVC の内部を調べていることはわかっていますが、この種のテスト容易性を念頭に置いて設計されていないため、これが唯一の方法です。いくつかの内部クラスやメソッドを公開するなどの単純なことでさえ、大いに役立ちました!

4

2 に答える 2

2

ASP.NET MVC での属性ルーティングは、従来の規則ベースよりも少し複雑です。System.Web.Mvc.Controller.ExecuteCore()属性ルーティングの null を返す場所からレビューを開始しGetActionName()、アクション セレクターに実行するアクションを選択させることができます。次に、System.Web.Mvc.ControllerActionInvoker.FindAction()すべての魔法を実行し、RouteCandidates を見つけて、ActionNameSelectors、ActionSelectors などでそれらをフィルタリングする場所に ジャンプできます。

ASP.NET MVC ロジックをラップする実装でプル リクエストを作成しました。

追加する重要な点の 1 つ: 実装は非常に重く、多くのリフレクションがあります。ASP.NET チームが AttributeRoutingTest.csなどでルーティングをテストする方法を見てください。名前やパラメーターなどを返すアクションでモックされたコントローラーを返す独自の ControllerFactory を使用できます。私の意見では、これははるかに簡単です。

于 2014-03-26T15:49:03.727 に答える
0

@Anthony、特定の URL でどのルートがたどられているかだけを確認したい場合は、Cobisi Routing Assistant拡張機能をロードしてください。

Visual Studio IDE で、[ツール] -> [拡張機能マネージャー...] に移動します。次に、[オンライン ギャラリー] タブが選択されていることを確認し、検索ボックスに「cobisi」と入力します。拡張機能をインストールすると、[ツール] メニューに Cobisi (natch) という新しい項目が表示されます。

URL マッパーを選択し、プロジェクトがロックされているというエラーが表示された場合はプロジェクトのロックを解除し、URL を入力します。[マップ] ボタンをクリックすると、URL がどのようにルーティングされるかが表示されます。ルーティングの問題で立ち往生している場合は、非常に素晴らしいです、私見。

于 2014-03-25T16:41:51.090 に答える