[ASP.NET MVC 小牛之路]08 - Area 使用

來源:互聯網
上載者:User

[ASP.NET
MVC 小牛之路]08 - Area 使用

ASP.NET MVC允許使用 Area(地區)來組織Web應用程式,每個Area代表應用程式的不同功能模組。這對於大的工程非常有用,Area 使每個功能模組都有各自的檔案夾,檔案夾中有自己的Controller、View和Model,但對於管理也增加了一定的難度。

本文目錄


建立Area

右鍵工程選擇 添加->地區,彈出如下填寫Area的對話方塊:

點擊添加後,工程目錄結構如下:

和建立一個空MVC工程結構類似,Admin Area 有自己的 Controllers、Models 和 Views 檔案夾,不一樣的地方就是多了一個 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 方法中它為我們定義了一個預設路由,我們也可在這個方法中定義專屬於Admin Area的的其他路由。但有一點要注意,在這如果要給路由起名字,一定要確保它和整個應用程式不一樣。

AreaRegistrationContext 類的 MapRoute 方法和 RouteCollection 類的 MapRoute 方法的使用是一樣的,只是 AreaRegistrationContext 類限制了註冊的路由只會去匹配當前 Area 的 controller,所以,如果你把在 Area 中添加的 controller 的預設命名空間改了,路由系統將找不到這個controller 。

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 路由的註冊將會在路由註冊之後,路由系統是按順序來匹配的,所以這樣做會讓請求 Area 的 Controller 匹配到錯誤的路由。


Area的運行

在Area中添加controller、view和model和一般的添加是一樣的。在這,我們在Admin Area中添加一個名為 Home 的controller,代碼如下:

public class HomeController : Controller {            public ActionResult Index() {        return View();    }}

然後我們再為Index Acton添加一個View,代碼如下:

@{     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>

運行應用程式,然後將URL定位到/Admin/Home/Index,下面是運行結果:

到這,我們已經看到,Area中的的工作流程其實就是和根目錄下的流程是一樣的。但Area並不是一個完全獨立的工作空間,我們下面來看看。


Controller的歧義問題

試想一下,如果我們現在在根目錄的 Controller 檔案夾中也添加一個名為 Home 的 Controller,然後我們通過把URL定位到 /Home/Index,路由系統能匹配到根目錄下的 Controller 嗎?

在根目錄的 Controllers 檔案夾中添加好 HomeController 後,為Index添加View,內容隨意:

...<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>


如果要在當前Area產生指根目錄某個controller的連結,那麼只要把area變數置成Null 字元串就行,如下:

@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>

以上就是[ASP.NET MVC 小牛之路]08 - Area 使用的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.