背景:在实际API使用时,会存在对API进行管理维护,同时,api的路由地址可能会进行分组辨认(例如前缀统一加api或者业务名称);如果对每一个控制器进行路由特性标识比较麻烦且费时间,不容易维护。
解决:可以通过统一设置路由前缀,具体步骤如下:
1. 在.net 6 WebApi项目中添加继承IApplicationModelConvention的类,实现路由前缀添加:
public class RouteConvention : IApplicationModelConvention
{
private readonly AttributeRouteModel _routePrefix;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="routeTemplateProvider"></param>
public RouteConvention(IRouteTemplateProvider routeTemplateProvider)
{
_routePrefix = new AttributeRouteModel(routeTemplateProvider);
}
public void Apply(ApplicationModel application)
{
//遍历所有的 Controller
foreach (var controller in application.Controllers)
{
// 已经标记了 RouteAttribute 的 Controller
var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
if (matchedSelectors.Any())
{
foreach (var selectorModel in matchedSelectors)
{
// 在当前路由上 再 添加一个路由前缀
selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_routePrefix, selectorModel.AttributeRouteModel);
}
}
// 没有标记 RouteAttribute 的 Controller
var unmatchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
if (unmatchedSelectors.Any())
{
foreach (var selectorModel in unmatchedSelectors)
{
// 添加一个路由前缀
selectorModel.AttributeRouteModel = _routePrefix;
}
}
}
}
}
2. 添加自定义路由扩展静态类
/// <summary>
/// 自定义路由扩展类
/// </summary>
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));
}
}
3. 在Program.cs中添加控制器时注册上述自定义扩展方法:
builder.Services.AddControllers(opt =>
{
// 统一设置路由前缀
opt.UseCentralRoutePrefix(new RouteAttribute("apiv2"));
});
4.这样所有控制器中的action路由前边都会加一个apiv2