[ASP.NET
MVC Mavericks Road] 08 - エリア
ASP.NET MVC を使用すると、エリアを使用して Web アプリケーションを編成できます。各エリアは、アプリケーションの異なる機能モジュールを表します。これは大規模なプロジェクトの場合に非常に便利ですが、各機能モジュールが独自のコントローラー、ビュー、モデルを含む独自のフォルダーを持つことができますが、管理がある程度難しくなります。
この記事のディレクトリ
エリアの作成
プロジェクトを右クリックし、追加->エリアを選択すると、次のようにエリアを入力するためのダイアログボックスが表示されます:
追加をクリックした後、プロジェクトのディレクトリ構造は次のとおりです:
空の MVC プロジェクトの作成にも同様の構造があります。違いは、追加の AdminAreaRegistration.cs ファイルがあることです。ファイルは、AdminAreaRegistration というクラスを定義します。その内容は次のとおりです。
namespace MvcApplication1.Areas.Admin { public class AdminAreaRegistration : AreaRegistration { public override string AreaName { get { return "Admin"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Admin_default", "Admin/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); } } }
システムによって自動的に生成される AdminAreaRegistration クラスは、抽象クラス AreaRegistration を継承し、
AreaName 属性と RegisterArea メソッドをオーバーライドします。 RegisterArea メソッドでは、デフォルト ルートを定義します。このメソッドでは、管理エリアに固有の他のルートも定義できます。ただし、注意すべき点が 1 つあります。ここでルートに名前を付ける場合は、アプリケーション全体とは異なる名前にする必要があります。
AreaRegistrationContext クラスの MapRoute メソッドは、RouteCollection クラスの MapRoute メソッドと同じように使用されます。ただし、AreaRegistrationContext クラスでは、登録されたルートが現在のエリアのコントローラーにのみ一致するように制限されるため、デフォルトの名前を変更すると、エリアに追加されたコントローラ スペースが変更されると、ルーティング システムはこのコントローラを見つけることができなくなります。
RegisterArea メソッドでは、手動で呼び出す必要はありません。 Global.asax の Application_Start メソッドには、これを行うための次のコードがすでに含まれています。
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
AreaRegistration.RegisterAllAreas メソッドを呼び出して、MVC アプリケーションがすべてのクラスを検索できるようにします。 AreaRegistration から継承し、そのようなクラスごとに RegisterArea メソッドを呼び出します。
注: Application_Start の登録メソッドの順序を簡単に変更しないでください。RouteConfig.RegisterRoutes メソッドを AreaRegistration.RegisterAllAreas メソッドの前に置くと、Area ルートの登録がルート登録の順序と一致します。そうすると、エリアを要求しているコントローラが間違ったルートと一致することになります。
エリア操作
エリアへのコントローラー、ビュー、モデルの追加は一般的な追加と同じです。ここでは、管理者エリアに Home という名前のコントローラーを追加します。コードは次のとおりです。
public class HomeController : Controller { public ActionResult Index() { return View(); } }
次に、Index Acton のビューを追加します。コードは次のとおりです。
@{ ViewBag.Title = "Index"; Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <p> <h2>Admin Area Index</h2> </p> </body> </html>
アプリケーションを実行し、 /Admin /Home/Index への URL、実行結果は次のとおりです:
この時点で、Area のワークフローが実際にはルート ディレクトリのプロセスと同じであることがわかりました。ただし、Area は完全に独立したワークスペースではありません。以下を見てみましょう。
コントローラーのあいまいさの問題
想像してみてください。ルート ディレクトリのコントローラー フォルダーに Home という名前のコントローラーも追加し、URL を /Home/Index に指定すると、ルーティング システムは、コントローラはルートディレクトリにありますか?
ルート ディレクトリの Controllers フォルダーに HomeController を追加した後、インデックスにビューを追加します。
... <body> <p> <h2>Root Index</h2> </p> </body> ...
ルーティングは RouteConfig でシステムによって定義されているものを使用します。 cs ファイル:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
プログラムを実行し、URL は /Home/Index にあります。その結果、次のエラー メッセージが表示されます:
出现这个问题是因为路由系统进行匹配的时候出现了Controller同名的歧义。
当Area被注册的时候,Area中定义的路由被限制了只寻找 Area 中的Controller,所以我们请求 /Admin/Home/Index 时能正常得到 MvcApplication1.Areas.Admin.Controllers 命名空间的 HomeController。然而我们在RouteConfig.cs文件的RegisterRoutes方法中定义的路由并没有类似的限制。
为了解决这个问题,我们需要在RouteConfig.cs文件中定义的路由中加上对应的 namespaces 参数。RouteConfig.cs 中修改后的路由如下:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, namespaces: new[] { "MvcApplication1.Controllers" } ); }
运行程序,如下结果说明解决了同名歧义问题:
添加了 namespaces 参数后,路由系统在对这个路由进行匹配时,优先匹配指定命名空间的controller,如果匹配到则即刻停止查找,如果在指定的命名空间下没有匹配到对应的controller,再按照一般的方式进行匹配。
生成Area URL链接
关于Area的URL链接生成,可以分为这么三种情况:第一种是在当前Area生成指向当前Area的链接;第二种是生成指向其他Area的链接;第三种是在某个Area中生成指向根目录的链接。下面是这三种情况生成链接的方法,使用的路由定义是系统默认的。
如果要在Area中生成当前Area的URL链接,直接用下面的方法就行:
@Html.ActionLink("Click me", "About")
它根据当前所在的Area和Controller会生成如下Html代码:
<a href="/Admin/Home/About">Click me</a>
如果要生成其他Area的URL链接,则需要在Html.ActionLink方法的匿名参数中使用一个名为area的变量来指定要生成链接的Area名称,如下:
@Html.ActionLink("Click me to go to another area", "Index", new { area = "Support" })
它会根据被指定的Area去找路由的定义,假定在Support Area中定义了对应的路由,那么它会生成如下链接:
<a href="/Support/Home/Index">Click me to go to another area</a>
以上就是[ASP.NET MVC 小牛之路]08 - Area 使用的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!
如果要在当前Area生成指根目录某个controller的链接,那么只要把area变量置成空字符串就行,如下:@Html.ActionLink("Click me to go to top-level part", "Index", new { area = "" })
它会生成如下Html链接:<a href="/Home/Index">Click me to go to top-level part</a>