zoukankan      html  css  js  c++  java
  • 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中的路由特性以及呈现母版页的几种方式,文中若有不当之处或者未涉及之处,欢迎补充以及批评。我们下节见。

  • 相关阅读:
    项目实现多数据库支持 规格严格
    KeyTool 4096 RSA JDK1.5 1.4 规格严格
    KeyTool用法 规格严格
    Tomcat ssl配置 规格严格
    redmine install 规格严格
    zlib1.2.5的编译 规格严格
    Class unload 规格严格
    Ubuntu 8.10 “Intrepid Ibex” 发布时间表确定
    22项Windows或Mac不能而Linux可以的事
    英语谚语
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/5503488.html
Copyright © 2011-2022 走看看