asp.net core 系列 6 MVC框架路由(下)

一.URL 生成

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

//
        // 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(); } public IActionResult Destination() { return View(); } // Index.cshtml 
      @Html.Raw(ViewData["url"].ToString())

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

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

 

  1.2 属性路由下的url生成

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

//首先不用传统路由,去掉了routes.MapRoute
      public void Configure(IApplicationBuilder app) { app.UseMvc(); } [Route("")] public IActionResult Index() { // Generates /custom/url/to/destination 
            var url = Url.Action("Destination"); var urlAddress = "<a href=\"" + url + "\" >"+url+"</a>"; ViewData["url"] = urlAddress; return View(); } [HttpGet("custom/url/to/destination")] public IActionResult Destination() { return View(); } 

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

  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(); } public IActionResult Destination(int id,string color) { return View(); } 

  1.4 根据路由名称生成 URL

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

[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("custom/url/to/destination", Name = "Destination_Route")] public IActionResult Destination() { return View(); }

  1.5  其它生成

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

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

 

二. 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; public CountrySpecificAttribute(string countryCode) { _countryCode = countryCode; } public int Order { get { return 0; } } public bool Accept(ActionConstraintContext context) { return string.Equals( context.RouteContext.RouteData.Values["id"].ToString(), _countryCode, StringComparison.OrdinalIgnoreCase); } }
//应用路由的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

相关文章
相关标签/搜索