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 ==
&& 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:

  1. 本代码支持 Area ,并会对 Area 名称也进行转义。
  2. 本代码使用自定义路由的方式实现功能,所以可能对预定义路由有影响。
  3. 更多与路由相关的信息可参见:https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing
  4. 本代码参考了其他代码,详见:https://stackoverflow.com/questions/40334515/automatically-generate-lowercase-dashed-routes-in-asp-net-core
  5. 码农很忙授权中心已经启用了本代码,演示:https://passport.coderbusy.com/

ASP.NET CORE MVC 实现减号分隔(Kebab case)样式的 URL的更多相关文章

  1. Pro ASP.NET Core MVC 6th 第三章

    第三章 MVC 模式,项目和约定 在深入了解ASP.NET Core MVC的细节之前,我想确保您熟悉MVC设计模式背后的思路以及将其转换为ASP.NET Core MVC项目的方式. 您可能已经了解 ...

  2. ASP.NET Core MVC/WebAPi 模型绑定探索

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  3. ASP.NET Core MVC 配置全局路由前缀

    前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Ap ...

  4. ASP.NET Core MVC 中的 [Controller] 和 [NonController]

    前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...

  5. ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

    原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio 作者:Mike Wasson 和 Rick Anderso ...

  6. ASP.NET Core 中文文档 第二章 指南(4.1)ASP.NET Core MVC 与 Visual Studio 入门

    原文:Getting started with ASP.NET Core MVC and Visual Studio 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:刘怡(Alex ...

  7. ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览

    原文:Overview of ASP.NET Core MVC 作者:Steve Smith 翻译:张海龙(jiechen) 校对:高嵩 ASP.NET Core MVC 是使用模型-视图-控制器(M ...

  8. ASP.NET Core MVC TagHelper实践HighchartsNET快速图表控件-开源

    ASP.NET Core MVC TagHelper最佳实践HighchartsNET快速图表控件支持ASP.NET Core. 曾经在WebForms上写过 HighchartsNET快速图表控件- ...

  9. ASP.NET Core MVC 在linux上的创建及发布

    前言 ASP.NET core转眼都发布半月多了,社区最近也是非常活跃,虽然最近从事python工作,但也一直对.NET念念不忘,看过了园区大神们搭建的Asp.net core项目之后,自己也是跃跃欲 ...

随机推荐

  1. 基础数据类型的补充和深浅copy

    一:关于str 的操作方法补充 1,s.isspace()   判断字符串是否只由空格组成,是,为True,否则,为False. s = ' ' #只能是以至少一个空格组成的字符串(全空格) prin ...

  2. java基础复习1

    jre:Java运行环境 jdk:Java开发工具(包含jre) java两大机制:JVM (java虚拟机) 垃圾回收 变量的分类: 1.按数据类型分: 1)基本数据类型:8种 整型:byte sh ...

  3. maven项目使用jacoco插件检测代码覆盖率详细配置

    使用maven构建项目(java项目或者web项目都可以) jacoco插件的配置参考官方网址:http://www.eclemma.org/jacoco/trunk/doc/maven.html ( ...

  4. git 文件状态与工作区域

    在上一篇简单讲述了文件状态与工作区域,在这里结合相关git命令详细了解文件的状态变更. 目录 1. 介绍 2. 常用命令 3. 实际操作 1. 介绍 git的文件状态是其git核心内容,了解后对后续的 ...

  5. 腾讯工程师带你深入解析 MySQL binlog

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 本文由 腾讯云数据库内核团队 发布在云+社区 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的red ...

  6. js swipeDelete 滑动删除

    先上图看看整体实际效果 看看用法 与参数 默认参数 var defaults = { distance:80, //滑动距离 units:'px', //默认单位 touchStart:functio ...

  7. Spring中Quartz的配置及corn表达式

    Quartz可以用来执行任务调度功能,如间隔一定时间调用执行任务.用起来还是蛮方便的.只要将你要调用的类配置到Spring配置文件即可. 在Spring的配置文件中配置Quartz. <!-- ...

  8. z-index在IE中的坑

    在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的x轴,y轴以及表示层叠的z轴.对于每个html元素,都可以通过设置z-index属性来设置该元素在视觉渲染模型中的层叠顺序. z-in ...

  9. MySQL数据库学习笔记----MySQL多表查询之外键、表连接、子查询、索引

    本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...

  10. pat 1014 1017 排队类问题

    1.用循环模拟时间 2.采用结构体模拟客户和窗口对象 3.合理处理边界,去除无用信息 4.使用自带排序sort()结合自定义功能函数compare()实现排序