ASP.NET MVC之路由特性以及母版頁呈現方式(十二)


前言

這一節我們開始講講基礎的東西也就是如題目所言,個人覺得當學習或者利用MVC時,必須得知道最新迭代版本新增了什么,至少得知道MVC 3、MVC 4或者MVC 5有什么區別,而不至於當利用到低版本時,出現某些特性就懵逼以至於認為是代碼出了問題,這一點是很明確需要我們去了解。

話題

在MVC 5之前都是基於約定的路由,如下:

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

對應的控制器則是Home,方法則是Index。此時在該控制器以及方法是實際存在的,當我們有某種需求不想對應其真實的路由時,則不滿足我們的要求。所以在MVC 5和Web APi 2中則出現了一個新的特性名叫路由特性。通過我們定義的控制器和Action,此時我們利用路由特性則可以更靈活的去控制URL。請往下看。

MVC路由特性

控制器路由特性

此時我們添加此控制器路由特性,如果我們此時不需要對某一個Action執行特殊的映射,則此時將應用到該控制器下的所有Action。

    [RoutePrefix("MyHome")]
    public class HomeController : Controller
    {
       
        public ActionResult Index()
        {
            return View();
        }
     }

此時則對應如下:

我們還可以定義默認Action:如下:

    [RoutePrefix("MyHome")]
    [Route("{action = index}")]
    public class HomeController : Controller
    {
       public ActionResult Index()
        {
            return View();
        }
    }

很棒,出錯了,結果如下:

比較出乎意料,最終對默認的Action進行如下修改,刪除之間的空格則好使:

 [Route("{action=index}")]

Action路由特性

通過在Action上定義一個特性使其應用到控制器上具體的Action方法。

    public class HomeController : Controller
    {
        [Route("cnblogs/{id:int:min(1)}")]  //訪問: cnblogs/1 public ActionResult Index(int id)
        {
            return View();
        }

        [Route("cnblogs/about")]         //訪問: cnblogs/about public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()   //訪問: Home/Contact
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }

區域路由特性

我們同樣可以使用路由區域特性來定義一個控制器屬於一個區域,我們知道來查找區域下的方法時通過區域注冊類來實現,若我們將一個區域中所有的控制器利用區域特性來實現,那么此時區域注冊類即 AreaRegistration 可以被移除掉。我們通過如下一個例子來看看。

    [RouteArea("Admin")]
    [RoutePrefix("menu")]
    [Route("{action}")]
    public class MenuController : Controller
    {
        // 路由: /admin/menu/login
        public ActionResult Login()
        {
            return View();
        }

        // 路由: /admin/menu/products
        [Route("products")]
        public ActionResult GetProducts()
        {
            return View();
        }

        // 路由: /categories
        [Route("~/categories")]
        public ActionResult Categories()
        {
            return View();
        }
    }

注意

(1)路由特性必須在基於約定的路由之前進行配置。

(2)當組合使用路由特性和基於約定路由時,此時未有使用路由特性時,則基於約定路由有效。

(3)當只有路由特性時,對於定義基於約定而沒有使用路由特性的Action方法時,此時將不會被訪問到。

使用路由特性的時機 

基於約定的路由是比較復雜並且能夠支持一個確定的URI,但是我們可以通過使用路由特性來非常容易的定義URI模式。

例如有如下場景:在網上購物客戶下單時,根據客戶Id來下單,此時則有類似這樣的URI: client/clientId/orders ,此時這種情況我們很難利用基於約定的路由去進行控制,即使能使用基於約定的路由能夠做出來,但是會略顯復雜或者不能很量化的表現出我們描述的那樣。所以基於描述,我們利用路由特性就可以輕松的寫出,如下:

        [Route("client/{clientId}/orders")]
        public IEnumerable<string> GetOrdersByClient(int clientId)
        {
            return Enumerable.Empty<string>();
        }

啟動路由特性

上面說了那么多,即使如上述那樣使用了路由特性也不會有任何效果,因為在MVC 5中默認未啟動路由特性,我們需要在路由配置文件 RouteConfig 中的 RegisterRoutes 方法中進行如下注冊即可,so  easy。

     routes.MapMvcAttributeRoutes();

若只使用路由特性則可以在該方法中刪除如下基於約定的路由。

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

MVC呈現母版頁 

MVC中的模板想必大家再熟悉不過了,在建立MVC的默認項目中在 Views/Shared/ 文件夾下就有一個主默認母板頁面 _ViewStart 。這里我們需要討論的是呈現母版頁的不同方式。

那么問題來了,有可能出現這樣一個場景:當需要控制用戶訪問權限時,此時不同角色的用戶對應的母版頁頁面可能不同,此時我們應該如何去做呢?

方式一

我們可以在 _ViewStart 母版頁頁中進行如下修改來對應不同的母版頁,不同的角色對應不同的控制器,當授權於對應的控制器則呈現對應的母版頁,所以此時我們只需要得到該控制器即可。

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();

    string layout = "";
    if (controller == "Admin")
    {
        layout = "~/Views/Shared/_AdminLayout.cshtml";
    }
    else
    {
        layout = "~/Views/Shared/_Layout.cshtml";
    }

    Layout = layout;
}

方式二

因為View方法有八個重載,最后一個重載的三個參數依次為視圖名稱,母版頁名稱,以及模型對象。所以此時可以我們直接通過ActionResult來呈現母版頁。

public ActionResult Index()
{
 var model = new UserModel();
 return View("Index", "_AdminLayout", model);
}

方式三

最直接的則是在對應的頁面定義母版頁即可。

@{
 Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

總結 

本節介紹了MVC 5中的路由特性以及呈現母版頁的幾種方式,文中若有不當之處或者未涉及之處,歡迎補充以及批評。我們下節見。

 


免責聲明!

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



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