1.URL 生成
MVC 应用程序可以使用路由的 URL 生成功能, 生成指向操作 (Action) 的 URL 链接. IUrlHelper 接口用于生成 URL, 是 MVC 与路由之间的基础部分. 在控制器, 视图和视图组件中, 可通过 Url 属性找到 IUrlHelper 的实例. 在此示例中, 将通过 Controller.Url 属性使用 IUrlHelper 接口来生成指向另一项操作的 URL.
- public class HomeController : Controller
- {
- public IActionResult Index()
- {
- var url1= Url.Action("Privacy");//Url:Home/Privacy
- var url2 = Url.Action("Error");//Url:Home/Error
- var url3 = Url.Action("Article");//Url:Blog/Article
- var msg = $"url1: {url1}";
- msg += $"\r\nurl2: {url2}";
- msg += $"\r\nurl3: {url3}";
- return Content(msg);
- }
- [HttpGet("custom/url/to/privacy")]// 定义一个路由模版
- public IActionResult Privacy()
- {
- return View();
- }
- public IActionResult Error(string code)
- {
- return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
- }
- }
响应结果:
如果 Url.Action 方法都只设置 Action 名称, 那么 IUrlHelper 接口会获取通过指向当前所在控制器里存在的 Action 操作, 然后生成 URL. 如果当前控制器里 Action 操作自定义路由模版, 则会生成对应路由模版 URL. 如果 Action 不存在当前控制器里, 则会生成空字符串的 URL.
2.URL 生成方式
2.1 根据操作名称生成 URL
Url.Action (IUrlHelper. Action) 可以通过指定控制器 (Controller) 名称和操作 (Action) 名称来生成要链接的内容. 而重载方法里还包含添加路由值对象, 比如 Url.Action("Home", "Index", new { id = 17 }), 此处路由值对象就是 new { id = 17 }(路由值对象通常是匿名类型的对象). 下面我们通过示例来看看:
- public class HomeController : Controller
- {
- public IActionResult Index(int id)
- {
- var url = Url.Action("Index", "Home", new { id = 17, color = "red", sex = "m" });
- return View();
- }
- }
通过 DEBUG 查看生成 URL:
2.2 根据路由生成 URL
上面的代码演示了如何通过传入控制器和操作名称来生成 URL.IUrlHelper 还提供 Url.RouteUrl 系列的方法. 这些方法类似于 Url.Action, 但它们不会将 action 和 controller 的当前值复制到路由值. 最常见的用法是指定一个路由名称, 以使用特定路由来生成 URL, 通常不指定控制器或操作名称.
- public class HomeController : Controller
- {
- public IActionResult Index(int id)
- {
- var url = Url.RouteUrl("Privacy_Name");
- return View();
- }
- [HttpGet("custom/url/to/privacy",Name = "Privacy_Name")]// 定义一个路由模版
- public IActionResult Privacy()
- {
- return View();
- }
- }
通过 DEBUG 查看生成 URL:
2.3 在 html 中生成 URL
IHtmlHelper 提供 HtmlHelper 方法 HTML.BeginForm 和 HTML.ActionLink, 可分别生成 < form > 和 <a > 元素. 这些方法使用 Url.Action 方法来生成 URL, 并且采用相似的参数. HtmlHelper 的配套 Url.RouteUrl 为 HTML.BeginRouteForm 和 HTML.RouteLink, 两者具有相似的功能.
- @using (HTML.BeginForm("Article", "Blog", FormMethod.Get, new {
- name = "nForm", id = "idForm"
- })){
- }
- @HTML.ActionLink("Article", "Article", "Blog")
通过浏览器工具查看生成 HTML:
2.4 在操作结果中生成 URL
以上示例展示了如何在控制器中使用 IUrlHelper. 不过, 控制器中最常见的用法是将 URL 生成为操作结果的一部分. ControllerBase 和 Controller 基类为操作结果提供简便的方法来引用另一项操作. 一种典型用法是在接受用户输入后进行重定向.
- public IActionResult Edit(int id, Customer customer)
- {
- if (ModelState.IsValid)
- {
- // Update DB with new details.
- return RedirectToAction("Index");
- }
- return View(customer);
- }
3. 区域(Area)
区域是 ASP.NET 功能, 它提供了一种将 ASP.NET Core web 应用程序划分为更小的功能组的方法, 每个功能组都有自己的一组 Razor Pages, 控制器 (Controllers), 视图(Views) 和模型 (Models). 区域实际上是应用程序内的结构. 在 ASP.NET Core Web 项目中, Pages, 模型, 控制器和视图等逻辑组件保存在不同的文件夹中. ASP.NET Core 运行时使用命名约定来创建这些组件之间的关系. 对于大型应用程序, 将应用程序区分为独立的高级功能区域可能更有利. 例如, 具有多个业务单位(如结账, 计费, 搜索等) 的电子商务应用程序. 每个单位都有自己的区域, 以包含视图, 控制器, Razor Pages 和模型. 下面的示例我们根据采购 (Purchase) 和销售 (Sale) 订单两个业务场景在 MVC 中配置使用默认传统路由和区域路由:
- public class Startup
- {
- public void Configure(IApplicationBuilder App)
- {
- App.UseMvc(routes =>
- {
- routes.MapAreaRoute(
- name: "MyAreaPurchase",
- areaName: "Purchase",
- template: "Purchase/{controller}/{action}/{id?}");
- routes.MapAreaRoute(
- name: "MyAreaSale",
- areaName: "Sale",
- template: "Sale/{controller}/{action}/{id?}");
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
- // 等价于
- //routes.MapAreaRoute("purOrder_route", "Purchase",
- //"Purchase/{controller}/{action}/{id?}");
- //routes.MapAreaRoute("saleOrder_route", "Sale",
- //"Sale/{controller}/{action}/{id?}");
- //routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
- });
- }
- }
在上面的示例中, 路由值将与以下操作匹配:
- [Area("Purchase")]
- public class PurOrderController : Controller
- {
- public IActionResult Index()
- {
- return View();
- }
- }
- [Area("Sale")]
- public class SaleOrderController : Controller
- {
- public IActionResult Index()
- {
- return View();
- }
- }
在每个控制器加入 AreaAttribute 属性是表示该控制器是某个区域的一部分, 比方说, PurOrderController 控制器位于 Purchase 区域中, SaleOrderController 控制器位于 Sale 区域中. 而没有 [Area] 属性的控制器不是任何区域的成员, 在路由提供 area 路由值时不匹配时, 打开对应控制器下的视图时将无法打开. 在上面的示例中, 只有所列出 PurOrderController,SaleOrderController 控制器下视图 Index 的路由值 { area = Purchase, controller = PurOrder, action = Index } ,{ area = Sale, controller = SaleOrder, action = Index }匹配才能打开对应链接.
4. 实现 IActionConstraint 的路由约束
实现 IActionConstraint 约束最简单的方法是创建派生自 System.Attribute 的类, 并将其置于操作 (Action) 和控制器 (Controller) 上. MVC 将自动发现任何应用为属性的 IActionConstraint 属性, 便对应用程序模型应用程序进行约束. 在下面的示例中, 对路由数据中的国家 / 地区选择操作进行约束.
- 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)
- {
- string routeDataValue = context.RouteContext.RouteData.Values["id"] == null ? "": context.RouteContext.RouteData.Values["id"].ToString();
- return string.Equals(
- routeDataValue,
- _countryCode,
- StringComparison.OrdinalIgnoreCase);
- }
- }
- public class HomeController : Controller
- {
- [CountrySpecific("en-us")]
- public IActionResult Index(string id)
- {
- return View();
- }
- }
根据官网解释 IActionConstraint.Order 是顺序约束意思, 比如 HomeController 控制器上有 [CountrySpecific("en-us")] 和[HttpGet](或者其他自定义属性约束)属性约束, 数值较低的属性约束先运行. 响应结果通过下面表格进行分析:
Route Url | Result |
[SERVICE_NAME]/Home/Index/en-us | 200 |
[SERVICE_NAME]/Home/Index/zh-cn | 404 |
通过以上的表格可以知道, 在此例中, 当 Index 传入路由值 (en-us) 匹配时, Accept 方法返回 true 以表示该操作是匹配项, 然后可以打开连接, 反之传入值 (zh-cn) 不匹配, 则 404.
参考文献:
在 ASP.NET Core 中路由到控制器操作
来源: https://www.cnblogs.com/wzk153/p/10996179.html