MVC Area領域處理以及T4MVC的使用


第一部分:(摘選自http://www.cnblogs.com/HuiTai/archive/2012/07/24/MVC-12.html 輝太

(這部分作者寫的很詳細,直接摘過來了)

MVC框架支持組織一個web應用程序到的區域,每個區域代表應用程序的功能性組比如賬單、客戶支持,等等,這在一個大的項目是非常有用的,那里有 一套單一的文件夾,所有的控制器,視圖和模型可以變得難以管理。每個MVC區域是有自己的文件夾結構,允許您分開管理。這使得它更顯而易見哪個項目元素相 互關聯應用程序的功能區域,這有助於多個開發人員同事處理項目而沒有彼此胡想不干擾。區域是支持主要通過路由機制。

我們從新新建一個MVCweb應用程序("MVCArea"),創建好項目,我們直接演示怎么給項目添加一個區域進來具體如下圖3.-4.

圖3.圖4.

 

當我們創建好我們的區域之后項目的結構會變成如下圖5所示。

 

圖 5.

OK這里你可以看一套類似與MVC文件機制東東出來,這個就是我們創建的區域關於這個東西后面慢慢來學習他,我們現在只關心他那個自動創建 AdminAreaRegistration.cs的文件里面是怎么一回事,不看內容就憑着這個名字猜一下,大概就路由扯上關系了。OK,打開看 看,AdminAreaRegistration.cs的代碼如下:

復制代碼
using System.Web.Mvc;

namespace MvcArea.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 }
            );
        }
    }
}
復制代碼

OK,可以看出上面代碼我加粗標識的RegisterArea方法十分有意思,在這個區域里注冊一個路由的URL模式"  Admin/{controller}/{action}/{id}",當然我們可以在這里定義其他的URL模式,但是你要知道你這這里定義的話只在該區 域里有效,也就是你額外定義的路由機制的持有權在該區域內。

我們不需要采取任何行動來確保這個注冊方法被調用。因為Global.asax文件里的Application_Start方法在我們創建區域的時 候為自動為我們注冊進去,那么我們來打開Global.asax文件里的Application_Start方法看看,具體代碼如下:

復制代碼
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
復制代碼

可以看到是OK的,接下我們在我們創建的Admin區域里添加一個控制器("Controller")和方法("Action")和一些視圖("View")來看看效果,首先添加一個控制器("Controller"),如下圖6.

圖6.創建HomeController,具體的代碼如下:

復制代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcArea.Areas.Admin.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Admin/Home/

        public ActionResult Index()
        {
            return this.View();
        }

    }
}
復制代碼

OK,我們在創建一個視圖,如下圖7.

圖7。創建好Index.cshtml,頁面的代碼如下:

@{
    ViewBag.Title = "Index";
}

<h2>Admin Area Index</h2>

OK,我們試着運行一下我們的Web項目,並且訪問一下他的路由" /Admin/Home/Index",結果如下圖8.

圖8.

貌似我們撒了一個謊言,我們試着訪問一下我們web項目的根路徑看看什么效果,運行如下圖9.

圖9.

OK,MVC路由機制一下找到了2個"HomeController"這下不知道去那個,就出錯了!

當一個地區注冊,任何路由,我們定義僅限於名稱空間關聯該區域。這就是我們為什么請求" /Admin/Home/Index "的時候。路由機制找到"HomeController"的命名空間MvcArea.Areas.Admin.Controllers。但 是 Global.asax文件的機制可不是這個樣子的,來看看我們默認的 Global.asax文件是怎么搞的,具體代碼如下:

復制代碼
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }
復制代碼

名為default的路由轉換傳入的URL從瀏覽器到主控制器HomeController行動上Index方法。在這一點上,我們得到一個錯誤, 因為有沒有命名空間的限制這條路線和MVC框架,可以看到兩個的HomeController類。所以我們就可以看到上面悲劇發生,我們對 Global.asax文件做簡單的處理,具體操作如下:

復制代碼
 public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
                new[] { "MvcArea.Controllers" } //指定命名空間
            );

        }
復制代碼

這種變化,確保在控制器的主要項目,給予優先解決的請求。

MVC框架中檢測到當前的請求與特定的區域, 然后出站的URL生成將會找到一個匹配只有在路線定義為該領域。比如在我們的Index.cshtml修改如下代碼所示:

復制代碼
@{
    ViewBag.Title = "Index";
}

<h2>Admin Area Index</h2>
@Html.ActionLink("Cilck me", "About")
復制代碼

運行項目,可以看到如下圖10的生成的連接.

圖10.

當然也可以修改如下代碼所示(創建一個鏈接到一個動作在不同的區域,或沒有區域內,您必須創建一個變量調用地區並使用它來指定區域的名字你想要的):

復制代碼
@{
    ViewBag.Title = "Index";
}

<h2>Admin Area Index</h2>
@Html.ActionLink("Cilck me", "About")
<br />
@Html.ActionLink("Click me to go to another area", "Index", new { area = "Support" })
復制代碼

運行的效果如下圖11.

圖11.

 

第二部分:(以下為個人添加)

在領域內部,各個action的訪問和不使用領域時相同,只要指定action和controller即可

@Html.ActionLink("文字","ActionName","ControllerName",new{可選參數})

但是在領域間進行交互訪問時,必須包含領域的路由信息,否則只能在當前領域進行查找。例如我們在首頁上添加一個鏈接,訪問Admin領域的Index頁面,寫法應該為:

@Html.ActionLink("test","Index","Home",new{area="Admin"},null)

我們使用 area=“Admin”來指明要訪問的領域。Admin為領域名稱,必須和AdminAreaRegistration.cs中的AreaName相同。

但是這樣還存在另一個問題,比如在維護時修改了Controller或者Action的名稱,而沒有修改View中相應的鏈接,程序運行時將出現嚴重錯誤。在此推薦使用T4MVC,它可以很好的管理控制器、方法和視圖。

在工程項目上右鍵點擊“Manage NuGet packages..”選擇安裝T4MVC,安裝成功后,會在項目下生成:

  • T4MVC.tt
  • T4MVC.settings.t4

T4MVC為每一個Controller創建了一個部分類,通過其中的方法我們可以很方便的取得控制器、方法或者視圖。

(注:如果添加了新的文件以后,T4MVC沒有更新,則右鍵點擊 .tt文件選擇Run Custom Tool,這時整個項目都會被重新編譯。)

例如上面提到的跨領域訪問的鏈接:

@Html.ActionLink("test","Index","Home",new{area="Admin"},null)
使用T4MVC以后簡化為:
@Html.ActionLink("A_admin", MVC.Admin.Home.Index())

而且在View中也可以使用智能感知,非常方便。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM