asp.net-mvc
ルーティング
サーチ…
前書き
ルーティングは、ASP.NET MVCがURIとアクションをどのように一致させるかを示します。ルーティングモジュールは、入ってくるブラウザリクエストを特定のMVCコントローラアクションにマッピングする役割を担います。
MVC 5は、属性ルーティングと呼ばれる新しいタイプのルーティングをサポートしています。名前が示すように、属性ルーティングは属性を使用してルートを定義します。属性ルーティングを使用すると、Webアプリケーション内のURIをより詳細に制御できます。
カスタムルーティング
カスタムルーティングでは、特定の着信要求を処理するための特別なルーティングが必要です。
カスタムルートを定義するには、ルートテーブルに追加するルートの順序が重要であることに注意してください。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// this is an advanced custom route
// you can define custom URL with custom parameter(s) point to certain action method
routes.MapRoute(
"CustomEntry", // Route name
"Custom/{entryId}", // Route pattern
new { controller = "Custom", action = "Entry" } // Default values for defined parameters above
);
// this is a basic custom route
// any custom routes take place on top before default route
routes.MapRoute(
"CustomRoute", // Route name
"Custom/{controller}/{action}/{id}", // Route pattern
new { controller = "Custom", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // Route pattern
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
);
}
controller
名とaction
名は予約されています。デフォルトMVCマップによって{controller}
クラスにURLの一部<controller>Controller
名前のメソッドを探し、次いで、及び<action>
任意の接尾辞を追加することなく。
{controller}/{action}/{parameter}
テンプレートを使用してルートのファミリを作成することが魅力的かもしれませんが、コントローラの名前を変更するとアプリケーションの構造が変更され、URLがやや脆くなります。ユーザが保存したリンクを経路指定して分割します。
明示的なルート設定を優先:
routes.MapRoute(
"CustomRoute", // Route name
"Custom/Index/{id}", // Route pattern
new { controller = "Custom", action = nameof(CustomController.Index), id = UrlParameter.Optional }
);
(あなたが使用することはできませんnameof
、それは追加の接尾辞がありますように、コントローラ名のオペレータをController
ルートでコントローラ名を設定するときに省略されなければなりません)。
Mvcでカスタムルートを追加する
ユーザーはカスタムルートを追加して、コントローラー内の特定のアクションにURLをマッピングできます。これは、検索エンジンの最適化目的に使用され、URLを読みやすくします。
routes.MapRoute(
name: "AboutUsAspx", // Route name
url: "AboutUs.aspx", // URL with parameters
defaults: new { controller = "Home", action = "AboutUs", id = UrlParameter.Optional } // Parameter defaults
);
MVCでの属性ルーティング
経路定義の古典的な方法に加えて、MVC WEB API 2とMVC 5のフレームワークが導入されました。 Attribute routing
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// This enables attribute routing and must go before other routes are added to the routing table.
// This makes attribute routes have higher priority
routes.MapMvcAttributeRoutes();
}
}
コントローラ内で同じ接頭辞を持つルートの場合は、 RoutePrefix
属性を使用してコントローラ内のアクションメソッド全体に共通のプレフィックスを設定できます。
[RoutePrefix("Custom")]
public class CustomController : Controller
{
[Route("Index")]
public ActionResult Index()
{
...
}
}
RoutePrefix
はオプションであり、コントローラのすべてのアクションに接頭辞として付けられるURLの部分を定義します。
複数のルートがある場合、アクションをパラメータとしてキャプチャしてデフォルトルートを設定し、デフォルトルートを上書きする特定のアクションメソッドで定義された特定のRoute
属性がない限り、コントローラ全体に適用できます。
[RoutePrefix("Custom")]
[Route("{action=index}")]
public class CustomController : Controller
{
public ActionResult Index()
{
...
}
public ActionResult Detail()
{
...
}
}
ルーティングの基礎
url yourSite/Home/Index
をブラウザから要求すると、ルーティングモジュールはHomeController
クラスのIndex
アクションメソッドにリクエストをHomeController
ます。この特定のクラスの特定のメソッドにリクエストを送信する方法を知っていますか? RouteTableがあります。
すべてのアプリケーションにはルートテーブルがあり、そこにルートパターンと要求の送信先に関する情報が格納されています。したがって、mvcアプリケーションを作成するときには、既にルーティングテーブルに登録されているデフォルトルートがあります。これはRouteConfig.cs
クラスで確認できます。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
エントリには名前とテンプレートがあることがわかります。テンプレートは、リクエストが入ったときにチェックされるルートパターンです。デフォルトのテンプレートは、コントローラURLセグメントの値としてHome
、アクションセグメントの値としてIndex
を持ちます。つまり、要求にコントローラ名とアクションを明示的に渡していない場合、これらのデフォルト値が使用されます。これは、あなたがあなたのyourSite/Home/Index
とyourSite
アクセスしたときと同じ結果を得る理由です
ルートパターンの最後のセグメントとしてidというパラメータがあることに気づいたかもしれません。しかし、デフォルトでは、オプションであると指定します。それが私たちが試みたurlのid値を指定する必要がなかった理由です。
今度は、HomeControllerのIndexアクションメソッドに戻り、それにパラメータを追加します
public ActionResult Index(int id)
{
return View();
}
次に、このメソッドにビジュアルスタジオブレークポイントを設定します 。プロジェクトを実行して、ブラウザのyourSite/Home/Index/999
にアクセスします。ブレークポイントがヒットし、 id
パラメータで値999が使用可能になったことがわかります。
2番目のルートパターンを作成する
別のルートパターンに対して同じアクションメソッドが呼び出されるように設定したいとしましょう。ルートテーブルに新しいルート定義を追加することで、これを行うことができます。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// New custom route definition added
routes.MapRoute("MySpecificRoute",
"Important/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
//Default catch all normal route definition
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
私が追加した新しい定義にはImportant/{id}
パターンがあります。ここでidは再びオプションです。これは、あなたがあなたのyourSiteName\Important
かyourSiteName\Important\888
を要求したときに、それがHomeControllerの索引アクションに送信されることを意味します。
経路定義登録の順序
経路登録の順序は重要です。一般的なデフォルトルートの前に、常に特定のルートパターンを登録する必要があります。
キャッチオールルート
次のような非結合数のセグメントを許可するルートを作成したいとします。
- http://example.com/Products/ (すべての製品を表示)
- http://example.com/Products/IT
- http://example.com/Products/IT/Laptops
- http://example.com/Products/IT/Laptops/Ultrabook
- http://example.com/Products/IT/Laptops/Ultrabook/Asus
- 等
通常はルートテーブルの最後にルートを追加する必要があります。これは、次のようにすべてのリクエストを捕捉する可能性があるためです。
routes.MapRoute("Final", "Route/{*segments}",
new { controller = "Product", action = "View" });
コントローラでは、これを処理できるアクションは次のとおりです。
public void ActionResult View(string[] segments /* <- the name of the parameter must match the name of the route parameter */)
{
// use the segments to obtain information about the product or category and produce data to the user
// ...
}
クライアント側ルーティングを有効にするキャッチオールルート
単一ページアプリケーション(SPA)の状態をURLでエンコードすることをお勧めします。
my-app.com/admin-spa/users/edit/id123
これにより、アプリケーションの状態を保存および共有できます。
ユーザーがブラウザのアドレスバーにURLを入力すると、サーバーにアクセスすると、要求されたURLのクライアント側の部分を無視する必要があります。静的なhtmlファイルではなく、レンダリングされたRazorビュー(コントローラのアクションを呼び出した結果)としてSPAを提供する場合は、キャッチオールルートを使用できます。
public class AdminSpaController
{
[Route("~/admin-spa/{clienSidePart*}")]
ActionResult AdminSpa()
{
...
}
}
この場合、サーバーはSPAだけを返し、ルートに従って自身を初期化します。このアプローチは、 url-rewriteモジュールに依存しないため、より柔軟です。
エリア内の属性ルーティング
エリアで属性ルーティングを使用するには、登録エリアと[RouteArea(...)]
定義が必要です。
RouteConfig.cs
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
}
}
サンプル領域コントローラ属性ルーティング定義では、
[RouteArea("AreaName", AreaPrefix = "AreaName")]
[RoutePrefix("SampleAreaController")]
public class SampleAreaController : Controller
{
[Route("Index")]
public ActionResult Index()
{
return View();
}
}
エリアでUrl.Action
リンクを使用するUrl.Action
:
@Url.Action("Index", "SampleAreaController", new { area = "AreaName" })