.NET Core 2.1中如何替换路由属性中的自定义占位符
解决.NET Core 2.1中路由自定义占位符自动替换的问题
这个需求其实很好实现,和框架自动替换[controller]的思路完全一致。根据你的实际场景,我给你两种可行的方案:
方案一:直接修改路由模板(单个控制器场景)
如果只有这一个控制器需要替换{serverkey},最简单直接的方式就是把路由模板里的占位符直接换成固定值key,完全不需要额外代码:
[Route("api/key/[controller]")] [ApiController] [AuthorizationFilter] public class MonitoringController : Controller { // Code... }
这样访问api/key/Monitoring/Action就会直接映射到这个控制器的对应方法,完全符合你的预期。
方案二:自定义路由约定(批量处理多个控制器场景)
如果你的项目里有多个控制器都用到了{serverkey}占位符,想统一替换成key,那自定义路由约定是更高效的方式,和框架处理[controller]的原理相同:
第一步:创建自定义路由约定类
这个类会在应用启动时遍历所有控制器,自动替换路由模板中的占位符:
using Microsoft.AspNetCore.Mvc.ApplicationModels; public class ServerKeyRouteConvention : IControllerModelConvention { public void Apply(ControllerModel controller) { // 遍历控制器上的所有路由选择器 foreach (var selector in controller.Selectors) { if (selector.AttributeRouteModel != null) { // 将{serverkey}替换为固定值"key" selector.AttributeRouteModel.Template = selector.AttributeRouteModel.Template.Replace("{serverkey}", "key"); } } } }
第二步:注册自定义约定到Mvc配置
在Startup.cs的ConfigureServices方法中,把这个约定添加到Mvc的配置里:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { // 添加我们自定义的路由约定 options.Conventions.Add(new ServerKeyRouteConvention()); }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
这样所有带有{serverkey}占位符的路由模板,都会被自动替换成key,你不需要逐个修改控制器的路由属性。
扩展:动态替换占位符
如果你的serverkey不是固定值,而是需要从配置文件读取,只需要给约定类注入IConfiguration即可:
public class ServerKeyRouteConvention : IControllerModelConvention { private readonly string _serverKey; public ServerKeyRouteConvention(IConfiguration configuration) { // 从配置文件读取serverkey的值,默认值设为"key" _serverKey = configuration["ServerSettings:Key"] ?? "key"; } public void Apply(ControllerModel controller) { foreach (var selector in controller.Selectors) { if (selector.AttributeRouteModel != null) { selector.AttributeRouteModel.Template = selector.AttributeRouteModel.Template.Replace("{serverkey}", _serverKey); } } } }
然后注册的时候要通过依赖注入的方式添加:
options.Conventions.Add<ServerKeyRouteConvention>();
这样就可以根据配置动态替换占位符了。
测试验证
完成上述配置后,启动项目,访问api/key/Monitoring/你的Action名称,就能正确映射到MonitoringController的对应方法,和你预期的URL格式完全一致。
内容的提问来源于stack exchange,提问作者Voodoo
相关产品推荐
相关产品推荐

