0, 目录
整体架构目录: ASP.NET Core 分布式项目实战 - 目录
一, 前言
在开发项目的过程中, 我新创建了一个 controller, 发现 vs 会给我们直接在 controller 头添加前缀, 比如 [Route("API/[controller]")], 即在访问接口的时候会变成 http://localhost:8000/API/values, 但是如果控制器有很多个, 或者要进行版本迭代时, 我们会发现痛苦的时刻降临了, 要一个一个的修改.
如果在这个时候可以进行全局配置前缀那真是福利呀, 修改一处即可. 为了能达到此目的我们就来运用一下吧.
二, 配置
0, 在配置前我们先来看看接口的前缀吧. 立图为证
用 swagger 打开
1, 我们需要用到 IApplicationModelConvention 这个接口, 它是位于 Microsoft.AspNetCore.Mvc.ApplicationModels 命令空间下面.
MVC 框架有一些约定俗成的东西, 这个接口主就是用来定义一些 MVC 约定的东西. 我们就可以通过 Apply 方法中的 ApplicationModel 来修改或者添加一些约定, 而且 MV 框架本身在启动的时候会把此接口注入, 以便于我们使用.
不过我们还是要来看一下这个 ApplicationModel 对象里面有什么我们可以用到的地方, 我们继续深入:
看到这是不是很爽, 我们可以看一下 每个属性的给出的解释
ApiExplorerModel: 包括描述信息, 群组信息, 可见性等.
ControllerModel: 主要是 Comtroller 默认约定相关的了, 这个里面东西就比较多了, 有 控制器名称, 路由值, Actions 等, 我们接下去的配置也将会在此展开
IFilterMetadata : 空接口, 主要起到标记的作用.
2, 配置
第一步: 先定义一个类, 用来实现 IApplicationModelConvention 接口.
- /// <summary>
- /// 全局路由前缀配置
- /// </summary>
- public class RouteConvention : IApplicationModelConvention
- {
- /// <summary>
- /// 定义一个路由前缀变量
- /// </summary>
- private readonly AttributeRouteModel _centralPrefix;
- /// <summary>
- /// 调用时传入指定的路由前缀
- /// </summary>
- /// <param name="routeTemplateProvider"></param>
- public RouteConvention(IRouteTemplateProvider routeTemplateProvider)
- {
- _centralPrefix = new AttributeRouteModel(routeTemplateProvider);
- }
- // 接口的 Apply 方法
- public void Apply(ApplicationModel application)
- {
- // 遍历所有的 Controller
- foreach (var controller in application.Controllers)
- {
- // 1, 已经标记了 RouteAttribute 的 Controller
- // 这一块需要注意, 如果在控制器中已经标注有路由了, 则会在路由的前面再添加指定的路由内容.
- var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
- if (matchedSelectors.Any())
- {
- foreach (var selectorModel in matchedSelectors)
- {
- // 在 当前路由上 再 添加一个 路由前缀
- selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_centralPrefix,
- selectorModel.AttributeRouteModel);
- }
- }
- //2, 没有标记 RouteAttribute 的 Controller
- var unmatchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
- if (unmatchedSelectors.Any())
- {
- foreach (var selectorModel in unmatchedSelectors)
- {
- // 添加一个 路由前缀
- selectorModel.AttributeRouteModel = _centralPrefix;
- }
- }
- }
- }
- }
此处代码需要注意下, 上面代码分为两部分, 一部分是控制器有路由配置, 一部分是没有路由配置. 因此需要根据具体的情况来选择使用.
第二步: 添加上面后, 我们就定义一个类来插入我们的路由吧.
定义 MvcOptionsExtensions.cs, 此方法主要是扩展了 MVCoptions 类
- public static class MvcOptionsExtensions
- {
- /// <summary>
- /// 扩展方法
- /// </summary>
- /// <param name="opts"></param>
- /// <param name="routeAttribute"></param>
- public static void UseCentralRoutePrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute)
- {
- // 添加我们自定义 实现 IApplicationModelConvention 的 RouteConvention
- opts.Conventions.Insert(0, new RouteConvention(routeAttribute));
- }
- }
说明: routeAttribute 为我们自定的前缀内容.
第三步: 在 startup.cs 里面 ConfigureServices 方法添加配置信息
- #region 配置全局路由
- // 在各个控制器添加前缀 (没有特定的路由前面添加前缀)
- services.AddMvc(opt =>
- {
- opt.UseCentralRoutePrefix(new RouteAttribute("lg/v1/[action]"));
- //opt.UseCentralRoutePrefix(new RouteAttribute("API/[controller]/[action]"));
- });
- #endregion
说明: 上面的方括号在这边是有效的. 其中内容可以自定义.
第四步: 运行
1, 原先控制器路由前缀保留
2, 把原先的路由前缀去除
来源: https://www.cnblogs.com/guolianyu/p/9680899.html