ASP.NET CORE MVC 实现减号分隔(Kebab case)样式的 URL
ASP.NET CORE MVC 中,默认的 Route 模板是: /{controller}/{action} 。我们可以通过开启 URL 小写转换将 URL 变为小写,但此方式在 Controller 或者 Action 为一个词组时,生成的 URL 并不友好。假设我们有 UserController 和 AddUser 方法,则框架生成的 URL 可能是: /User/AddUser ,在开启小写转换的情况下可能是下面的结果: /user/adduser 。包含大写字符的 URL 并没有问题,但是小写的 URL 更加常规,而完全转换小写造成的问题就是 URL 的可读性很差。本文将提供一些代码,帮助框架生成减号分隔样式的 URL ,当应用了这些代码以后,生成的 URL 类似这样: /user/add-user 。 微软为我们提供了 RouteAttribute ,可以对 Controller 或者 Action 进行标记,以达到自定义访问路径的目的。这种方式非常强大,但在项目较大的情况下使用起来有些繁杂。毕竟手工对每一个 Controller 和 Action 进行标记也有不小的工作量。 ASP.NET CORE MVC 框架中定义了一个 IControllerModelConvention 接口,我们可以实现该接口在运行时为 Action 附加一个 Route 模型。在项目中新建 DashedRoutingConvention 类文件,代码如下:
public class DashedRoutingConvention : IControllerModelConvention { public void Apply(ControllerModel controller) { var hasRouteAttributes = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); if (hasRouteAttributes) { // This controller manually defined some routes, so treat this // as an override and not apply the convention here. return; } foreach (var controllerAction in controller.Actions) { foreach (var selector in controllerAction.Selectors.Where(x => x.AttributeRouteModel == null)) { var parts = new List<string>(); foreach (var attr in controller.Attributes) { if (attr is AreaAttribute area) { parts.Add(area.RouteValue); } } if ( parts.Count == 0 && controller.ControllerName == "Home" && controllerAction.ActionName == "Index" ) { continue; } parts.Add(PascalToKebabCase(controller.ControllerName)); if (controllerAction.ActionName != "Index") { parts.Add(PascalToKebabCase(controllerAction.ActionName)); } selector.AttributeRouteModel = new AttributeRouteModel { Template = string.Join("/", parts) }; } } } private static string PascalToKebabCase(string value) { if (string.IsNullOrEmpty(value)) { return value; } return Regex.Replace( value, "(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])", "-$1", RegexOptions.Compiled) .Trim() .ToLower(); } }
之后,将 DashedRoutingConvention 在 Startup.cs 中注册。
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(options => options.Conventions.Add(new DashedRoutingConvention())); }
至此,全部代码完毕。 Notices:
- 本代码支持 Area ,并会对 Area 名称也进行转义。
- 本代码使用自定义路由的方式实现功能,所以可能对预定义路由有影响。
- 更多与路由相关的信息可参见:https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing
- 本代码参考了其他代码,详见:https://stackoverflow.com/questions/40334515/automatically-generate-lowercase-dashed-routes-in-asp-net-core
- 码农很忙授权中心已经启用了本代码,演示:https://passport.coderbusy.com/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?