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

    当加载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("")]
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 的路由模板。

  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= , 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,通常不指定控制器或操作名称。

        [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");

二. 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 ;
}
} 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

asp.net core 系列 6 MVC框架路由(下)的更多相关文章

  1. asp.net core 系列 8 Razor框架路由(下)

    三.页面路由操作约定 接着上篇讲asp.net core 系列 7 Razor框架路由.在上篇继续第三节 "页面路由操作约定" 的最后一小节 AddPageRoute . 3.3. ...

  2. asp.net core 系列 5 MVC框架路由(上)

    一. 概述 介绍asp.net core路由时,我初步想了下,分几篇来说明.  路由的知识点很多,参考了官方文档提取出一些重要的知识点来说.    在ASP.NET Core中是使用路由中间件来匹配传 ...

  3. asp.net core 系列 7 Razor框架路由(上)

    一.概述 在上二篇中,主要是介绍了asp.net core mvc中路由的使用,这篇继续介绍路由在ASP.NET Core Razor中的使用.Razor Pages应该使用默认的传统路由,从应用程序 ...

  4. 【ASP.NET Core】- 搭建MVC框架

    1.使用最新版本的VS2017,并安装.NET Core2.0中相关开发工具   2.打开VS2017,点击文件-新建-项目,选择.NET Core中的ASP.NET Core Web 应用程序   ...

  5. 【目录】asp.net core系列篇

    随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...

  6. asp.net core系列 40 Web 应用MVC 介绍与详细示例

    一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...

  7. ASP.Net Core 2.2 MVC入门到基本使用系列 (三)

    本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...

  8. 【asp.net core 系列】4. 更高更强的路由

    0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...

  9. ASP.Net Core 2.2 MVC入门到基本使用系列 (二)

    本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...

随机推荐

  1. Java中超大文件读写

    如果文件过大不能一次加载,就可以利用缓冲区: File file = new File(filepath); BufferedInputStream fis = new BufferedInputSt ...

  2. 随笔【js】

    1.js是大小写敏感的 2. 区别 getElementBy ID , getElementsBy Name,  getElementsBy TagName以人来举例说明,人有能标识身份的身份证,有姓 ...

  3. Python爬虫开发与项目实战

    Python爬虫开发与项目实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1MFexF6S4No_FtC5U2GCKqQ 提取码:gtz1 复制这段内容后打开百度 ...

  4. mysql5.7.X版本only_full_group_by问题解决

    一.出错原因 最近因为开发数据库与部署数据库版本不同,带来了几个问题,其中only_full_group_by问题是之前没有遇到的. 具体报错如下 [Err] 1055 - Expression #1 ...

  5. android BLE Peripheral 模拟 ibeacon 发出ble 广播

    Android对外模模式(peripheral)的支持: 从Android 5.0+开始才支持. api level >= 21 所以5.0 之前设备,是不能向外发送广播的. Android中心 ...

  6. jdk12+tomcat9 配置

    jdk12 没有了jre的配置   直接配置path就可以了 tomcat常规配置,只是启动的时候麻烦一点   需要重新写入jdk jre jvm 到server.bat文件 参考文章: https: ...

  7. python学习:购物车程序

    购物车程序 product_list = [ ('mac',9000), ('kindle',800), ('tesla',900000), ('python book',105), ('bike', ...

  8. HTML/CSS实现的一个列表页

    又到休息日,白天没事跟朋友去逛逛街,侃大山,晚上了,上网无趣,于是就想起该练练了, 这次是做了一个页面,最上面是一个banner 用到了一个jQuery的逻辑判断当banner初始top值小于wind ...

  9. linq给list集合数据分页

    var lastlist= newlist.Skip(pageindex * pagesize).Take(pagesize);

  10. meta标签的用处详解

    meta标签的用处: 用来描述html文档的一个属性.列如作者.日期和时间,网页描述,关键字,页面刷新等. 是文档最基本的元数据 元数据(metadata): 用来概括描述数据的一些基本数据 meta ...