當一個大型的網頁專案區分許多子系統模組時,整個系統加總起來或許有上千上百個Controller或View,按照MVC的精神,把Controller,
View, Model分離,結果可能三個資料夾內有超多檔案,所有功能都混雜在一起,開發與維護起來相當不易,對網址的區隔與命名也想當困難,如果使用預設的Route(/{Controller}/{Action}),很難將相關的功能歸類。
仔細深入的探索MVC,就會發現MVC有提供區域(Area)的機制,讓相似的功能或整個子系統抽離,與其它子系統獨立,每個子系統有自己的設定,不會干預到其他子系統,在網址的分層上,也多了區域,使可讀性變得更高(/{Area}/{Controller}/{Action}),以下就來講解如何將Area分離:
1. 在MVC專案按下右鍵 ->[加入] -> [區域]。
2. 輸入區域名稱。
3. 可以看到在專案下多出了一個Areas的資料夾,Areas底下有剛剛建立的Admin區域,
Admin區域裡分別有Controllers和Views, Models的資料夾,整個結構和外面的Controllers, Views, Models相同,另外,VS在View裡也為此區域建了一個Web.config檔,打開仔細一看會發現和外層Views資料夾內的Web.config內容類似。
4. 在上圖中可以發現多一個沒看過的AdminAreaRegistration.cs檔,這個檔案是Admin區域自己的RouteConfig,AdminAreaRegistration要繼承AreaRegistration,這樣在Global.asax.cs裡Application_Start()時,AreaRegistration.RegisterAllAreas()這行才會找到有繼承AreaRegistration,將各自的RouteConfig註冊。
AdminAreaRegistration.cs:
AdminAreaRegistration.cs:
using System.Web.Mvc; namespace RouteTest.Areas.Admin { public class AdminAreaRegistration : AreaRegistration { public override string AreaName { get { return "Admin"; } } public override void RegisterArea( AreaRegistrationContext context ) { // Admin區域的Route context.MapRoute( name: "Admin_default", url: "Admin/{controller}/{action}/{id}", defaults: new { action = "Index", id = UrlParameter.Optional }, namespaces: new[] { "RouteTest.Areas.Admin.Controllers" } ); } } }
Global.asax.cs:
using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace RouteTest { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { // 註冊所有區域的Route AreaRegistration.RegisterAllAreas(); WebApiConfig.Register( GlobalConfiguration.Configuration ); FilterConfig.RegisterGlobalFilters( GlobalFilters.Filters ); RouteConfig.RegisterRoutes( RouteTable.Routes ); BundleConfig.RegisterBundles( BundleTable.Bundles ); } } }5. 接著再加入新的Controller(這裡限量加入一個AccountController)並在Controller裡加入Action與對應的View。
AccountController.cs:
using System.Web.Mvc; namespace RouteTest.Areas.Admin.Controllers { public class AccountController : Controller { // // GET: /Admin/Account/ public ActionResult Index() { return View(); } } }
6. 為了測試區域之間的連結能正常運作,限量在共用Layout裡加入各區域Controller
Index Action的連結,這裡要注意的是,因為_Layout.cshtml是在原本最外層的View裡,原本根據的是它原本的RouteConfig,就不用特別在意區域的問題,但有區域的分別時,所以會識別不了其他區域的RouteConfig,所以這時候就要在後面的RouteValue加入area的值,意思是該連接是會連結到該區域的某某Controller裡,area是Route內部運作時使用的變數,代表區域的名稱。
_Layout.cshtml:
_Layout.cshtml:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <header> <ul> @*/*@ <li>@Html.ActionLink( "Home-Index", "Index", "Home", new { area = "" }, null )</li> @*/Admin/Account*@ <li>@Html.ActionLink( "Account-Index", "Index", "Account", new { area = "Admin" }, null )</li> </ul> </header> @RenderBody() @Scripts.Render("~/bundles/jquery") @RenderSection("scripts", required: false) </body> </html>
最後看看執行結果,Admin Area的網址上多了Admin這層。
參考來源:
留言
張貼留言