zoukankan      html  css  js  c++  java
  • asp.net core 系列 6 MVC框架路由(下)

    一.URL 生成

      接着上篇讲MVC的路由,MVC 应用程序可以使用路由的 URL 生成功能,生成指向操作的 URL 链接。 生成 URL 可消除硬编码 URL,使代码更稳定、更易维护。 此部分重点介绍 MVC 提供的 URL 生成功能,并且仅涵盖 URL 生成工作原理的基础知识。 IUrlHelper 接口用于生成 URL,是 MVC 与路由之间的基础结构的基础部分。 在控制器、视图和视图组件中,可通过 Url 属性找到 IUrlHelper 的实例。

            //
            // mvc 框架的ControllerBase类下
            //摘要:
            //     Gets or sets the Microsoft.AspNetCore.Mvc.IUrlHelper.
            public IUrlHelper Url { get; set; }

      

      1.1 传统路由下的url生成

        下面示例中,通过使用IUrlHelper接口在index页面生成指向另一操作Destination的 URL超连接。

    复制代码
            [Route("Home/Index")]
            public IActionResult Index()
            {
                // Generates /Home/Destination
                var url = Url.Action("Destination");
                var urlAddress = "<a href="" + url + ""  >Click on to the Destination</a>";
                ViewData["url"] = urlAddress;
                return View();
            }
    
        </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> IActionResult Destination()
        {
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> View();
        }
    
       </span><span style="color: #008000;">//</span><span style="color: #008000;"> Index.cshtml     </span>
      @Html.Raw(ViewData[<span style="color: #800000;">"</span><span style="color: #800000;">url</span><span style="color: #800000;">"</span>].ToString())</pre>
    
    复制代码

        当加载index页面后,点击超连接"Click on to the Destination" 将进入后台控制器的Destination操作中。

        上面的 Url.Action 示例假定使用传统路由,但 URL 生成功能的工作方式与属性路由相似,只不过概念不同。 在传统路由中,路由值用于扩展模板。controller 和 action 的路由值通常出现在该模板中, 这种做法可行是因为通过路由匹配的 URL 遵守某项约定。 这里的扩展模板指的是routes.MapRoute来添加路由规则约定。

      1.2 属性路由下的url生成

        在属性路由中,controller 和 action 的路由值不能出现在模板中(也就是不会使用routes.MapRoute),它们用于查找要使用的模板。

    复制代码
          //首先不用传统路由,去掉了routes.MapRoute
          public void Configure(IApplicationBuilder app)
            {
                app.UseMvc();
            }
    
        [Route(</span><span style="color: #800000;">""</span><span style="color: #000000;">)]
        </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> IActionResult Index()
        {
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> Generates /custom/url/to/destination </span>
            <span style="color: #0000ff;">var</span> url = Url.Action(<span style="color: #800000;">"</span><span style="color: #800000;">Destination</span><span style="color: #800000;">"</span><span style="color: #000000;">);
            </span><span style="color: #0000ff;">var</span> urlAddress = <span style="color: #800000;">"</span><span style="color: #800000;">&lt;a href="</span><span style="color: #800000;">"</span> + url + <span style="color: #800000;">"</span><span style="color: #800000;">"  &gt;</span><span style="color: #800000;">"</span>+url+<span style="color: #800000;">"</span><span style="color: #800000;">&lt;/a&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">;
            ViewData[</span><span style="color: #800000;">"</span><span style="color: #800000;">url</span><span style="color: #800000;">"</span>] =<span style="color: #000000;"> urlAddress;
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> View();
        }
    
        [HttpGet(</span><span style="color: #800000;">"</span><span style="color: #800000;">custom/url/to/destination</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
        </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> IActionResult Destination()
        {
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> View();
        }
    </span></pre>
    
    复制代码

         生成如下图所示 :所以会生成与httpget配置的路径一样,是因为属性路由下的url生成,它们用于查找要使用的模板。MVC 生成一个包含所有属性路由操作的查找表,并匹配 controller 和 action 的值,以选择要用于生成 URL 的路由模板。

      1.3 根据action名称生成 URL

        Url.Action (IUrlHelper . Action) 以及所有相关重载都基于这样一种想法:用户想通过指定控制器名称和操作名称来指定要链接的内容。

    复制代码
            [Route("")]
            public IActionResult Index()
            {
                // Generates /Home/Destination/1?color=red
                var url = Url.Action("Destination","Home",new  { id=1 , color="red"});
                var urlAddress = "<a href="" + url + ""  >" + url + "</a>";
                ViewData["url"] = urlAddress;
                return View();
            }
    
        </span><span style="color: #0000ff;">public</span> IActionResult Destination(<span style="color: #0000ff;">int</span> id,<span style="color: #0000ff;">string</span><span style="color: #000000;"> color)
        {
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> View();
        }    </span></pre>
    
    复制代码

      1.4 根据路由名称生成 URL

        IUrlHelper 还提供 Url.RouteUrl 系列的方法。 这些方法类似于 Url.Action。Url.RouteUrl 指定一个路由名称,以使用特定路由来生成 URL,通常不指定控制器或操作名称。

    复制代码
            [Route("")]
            public IActionResult Index()
            {
                // Generates /custom/url/to/destination
                var url = Url.RouteUrl("Destination_Route");
                var urlAddress = "<a href="" + url + ""  >Click on to the Destination</a>";
                ViewData["url"] = urlAddress;
                return View();
            }
    
        [HttpGet(</span><span style="color: #800000;">"</span><span style="color: #800000;">custom/url/to/destination</span><span style="color: #800000;">"</span>, Name = <span style="color: #800000;">"</span><span style="color: #800000;">Destination_Route</span><span style="color: #800000;">"</span><span style="color: #000000;">)]
        </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> IActionResult Destination()
        {
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> View();
        }</span></pre>
    
    复制代码

      1.5  其它生成

         (1)在 HTML 中生成 URL: IHtmlHelper 提供 HtmlHelper 方法 Html.BeginForm 和 Html.ActionLink,可分别生成 <form> 和 <a>元素。 这些方法使用 Url.Action 方法来生成 URL,并且采用相似的参数。

        (2)在action中重定向:RedirectToAction("Index"); 

    二. area区域路由

        区域是一种 MVC 功能,用于将相关功能整理到一个组中,作为单独的路由命名空间(用于控制器操作)和文件夹结构(用于视图)。 通过使用区域,应用程序可以有多个名称相同的控制器,只要它们具有不同的区域。 通过向 controller 和 action 添加另一个路由参数 area,可使用区域为路由创建层次结构。

        下面是mvc文件结构,对于users控制器,在视图层多了一级Manage文件夹。如何使users控制器中AddUser操作关联AddUser.cshtml呢,下面使用区域路由来实现:

    复制代码
              app.UseMvc(routes =>
                {
                    //用于名为 Blog 的区域
                    routes.MapAreaRoute("blog_route", "Blog","Manage/{controller}/{action}/{id?}");
                    /*
                     * 注释的MapRoute与上面的区域路由作用一样
                    routes.MapRoute("blog_route", "Manage/{controller}/{action}/{id?}",
                    defaults: new { area = "Blog" }, constraints: new { area = "Blog" });
                    */
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
    复制代码
    复制代码
            //控制器上应用区域路由
           [Area("Blog")]      public class UsersController : Controller      {    // GET: /<controller>/      public IActionResult AddUser()      {   return View();      }      }
    复制代码

        在浏览器中输入/Manage/Users/AddUser 将自动进入AddUser()中,这是因为当前路由:Manage/{controller}/{action}/{id?}符合blog模板,所以使用Blog区域路由。

      

     三. IActionConstraint 路由约束

        实现IActionConstraint最简单的方法是创建派生自 System.Attribute 的类,并将其置于操作和控制器上。MVC 将自动发现任何应用属性IActionConstraint的操作和控制器。

        在下面的示例中,约束基于路由数据中的国家/地区代码选择操作,开发人员负责实现Accept 方法,当路由中id值为en-US时Accept 方法返回 true 以表示该操作是匹配项,一切按正常解析返回客户端。 如果Accept 方法返回false将不执行IActionConstraint标记的action,向客户端返回404错误。

    复制代码
    //定义ActionConstraint属性约束
    public class CountrySpecificAttribute : Attribute, IActionConstraint
        {
            private readonly string _countryCode;
    
        </span><span style="color: #0000ff;">public</span> CountrySpecificAttribute(<span style="color: #0000ff;">string</span><span style="color: #000000;"> countryCode)
        {
            _countryCode </span>=<span style="color: #000000;"> countryCode;
        }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> Order
        {
            </span><span style="color: #0000ff;">get</span><span style="color: #000000;">
            {
                </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
            }
        }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span><span style="color: #000000;"> Accept(ActionConstraintContext context)
        {
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">string</span><span style="color: #000000;">.Equals(
                context.RouteContext.RouteData.Values[</span><span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span><span style="color: #000000;">].ToString(),
                _countryCode,
                StringComparison.OrdinalIgnoreCase);
        }
    }</span></pre>
    
    复制代码
    复制代码
          //应用路由的action约束,并且路由中id值为en-US
           [CountrySpecific("en-US")]
            public IActionResult Privacy(string countryCode)
            {
                return View();
            }
    复制代码

        在浏览器测试时:如果输入http://localhost:30081/home/Privacy/zh-cn,则网页显示404。如果输入http://localhost:30081/home/Privacy/en-US 则符合约束,网页显示正常。

     

      参考文献

      官方资料:asp.net core routing

  • 相关阅读:
    3.流程控制语句
    pandas数据处理(一)pymongo数据库量大插入时去重速度慢
    windows下载安装redis
    Scrapy(一)爬知乎所有用户信息
    Mongodb去除重复的数据,pymongo去重
    selenium爬虫报错:Message: stale element reference: element is not attached to the page document 促成1分钟爬完斗鱼主播信息。
    用pyspider爬斗鱼主播信息
    曼城新闻情报站(二)Django框架的爬虫
    曼城新闻情报站(一)爬取3大网站的曼城新闻
    Beautiful Soup多线程爬取斗鱼所有主播信息(改良版)
  • 原文地址:https://www.cnblogs.com/owenzh/p/11212514.html
Copyright © 2011-2022 走看看