iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 26
0

Area 區域

MVC模式會將應用程式的模型邏輯與其呈現邏輯與商務邏輯分開。 在ASP.NET MVC中,此邏輯分隔同樣會在專案結構中實際實作,其中控制器和檢視會保留在使用命名慣例定義關聯的資料夾中。

不過,某些應用程式可能擁有大量Controller,而每一個Controller可能與多個View相關聯。針對這類應用程式,預設的ASP.NET MVC專案結構可能會變得十分龐雜。

為了容納大型專案,ASP.NET MVC 可以切割成多個區塊,稱為「區域」(Area)。 區域則提供將大型MVC架構分割成較小功能群組的方式。
一個區域就是應用程式中的一個MVC結構, 而一個應用程式可以包含數個MVC結構。

使用情境

  • 你的應用程式需要含有多種高階層邏輯的功能區塊
  • 你希望將專案依照功能區塊切割,並可以獨力運行。

Area特色

  • 一個ASP.Net MVC專案,可以包含數個Areas
  • 每個Area會有自己的MVC
  • 允許大型專案切割成各個功能群組並能獨立運行
  • 允許在不同的Area底下,有多個相同命名的Controller名稱(在下面範例會介紹如何達到)

實作

1.先來實作看看,先從專案按右鍵,「加入」/「區域」
http://ithelp.ithome.com.tw/upload/images/20170110/201038083SNYiVzOJ6.png

2.會產生一個Area的資料夾,裡面包了一層MVC
http://ithelp.ithome.com.tw/upload/images/20170110/2010380884WCj02wCQ.png

3.預設會產生一個cs檔去繼承AreaRegistration,並產生預設連線Area的預設Route條件。

    public class AdminAreaRegistration : AreaRegistration 
    {
        public override string AreaName 
        {
            get 
            {
                return "Admin";
            }
        }
        public override void RegisterArea(AreaRegistrationContext context) 
        {
            context.MapRoute(
                "Admin_default",
                "{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }

4.接著像往常一樣建立一個Controller,我們測試故意設定跟外面有一樣的Controller名稱「Home」。

namespace MVCProject.Areas.Admin.Controllers
{
    public class HomeController : Controller
    {
        // GET: Admin/Home
        public ActionResult Index()
        {
            return View();
        }
    }
}

5.接著建立一個空的「Index」
6.接著執行
http://ithelp.ithome.com.tw/upload/images/20170110/20103808mKWG1LCf6D.png
會出現找到多個與名為 'Home' 的控制器相符的類型。如果服務此要求 ('{controller}/{action}/{id}') 的路由沒有指定命名空間以搜尋符合該要求的控制器,就會發生這個情況。在這種情況下,請呼叫可接受 'namespaces' 參數的 'MapRoute' 方法的多載來註冊此路由。的問題。
意思是再跑Route的規則時,同一時間抓到
http://localhost:62990/Home/Index
http://localhost:62990/Admin/Home/Index
這兩個檔案。
打開RouteConfig檔案,會看到Route條件,上述兩個URL同時符合Controller=Home,action=Index

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

7.這時我們要新增namespaces: new[] {"MVCProject.Controllers"},讓他指定比對的namespaces,這樣就不會比對到Area底下的資料。

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            //routes.MapMvcAttributeRoutes();
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                namespaces: new[] {"MVCProject.Controllers"}
            );

8.接著當我們把外層MVC和Area切開之後,我們稍微改變一下Area裡面的Route規則,那他能更明確的指定我們URL的標準,我們加入Admin/

context.MapRoute(
                "Admin_default",
                "Admin/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );

9.接著執行程式,結果就能正常執行了
http://ithelp.ithome.com.tw/upload/images/20170110/20103808vBVBuHkqcl.png

http://ithelp.ithome.com.tw/upload/images/20170110/20103808FN6MDDABYR.png

延伸閱讀

http://kevintsengtw.blogspot.tw/2013/07/aspnet-mvc-area-backend.html
http://ithelp.ithome.com.tw/articles/10131687
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/areas


上一篇
Day25_Controller之ActionResult(2)
下一篇
Day27_Visual Studio 常用快速鍵
系列文
從Asp.Net MVC5的起跑點認識現代網站30

尚未有邦友留言

立即登入留言