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:

  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/


原文:https://www.coderbusy.com/archives/956.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spark SQL(九)之基于用户的推荐公式

一、基于用户的推荐公式 其中&#xff0c;S(u,K)表示与用户u最相似的K个用户&#xff0c;N(i)代表喜欢物品i的用户集合&#xff0c;rm表示用户v对物品i的评分。 二、代码 public class UserCFRecommendApp {public static void main(String[]args){SparkConf sparkConf new S…

jzoj6309-完全背包【贪心,背包】

正题 题目大意 完全背包&#xff0c;不过容量特别大。 解题思路 然后我们可以先做一个1∼200001\sim 200001∼20000的背包&#xff0c;然后枚举一个大小&#xff0c;然后将这个大小填入背包知道无法填入为止&#xff0c;然后剩下的空位在再一次背包就好。 codecodecode #incl…

拥抱.NET Core系列:MemoryCache 缓存过期

MSCache项目MSCache目前最新的正式版是 2.0.0&#xff0c;预览版是2.1.0&#xff0c;会与.NETCore 2.1一起发布。本篇用了2.0.0版本开源在GitHub上&#xff0c;仓库地址是&#xff1a;https://github.com/aspnet/CachingNuGet地址为&#xff1a;https://www.nuget.org/packages…

Spark SQL(十)之基于物品的推荐公式

一、基于物品的推荐公式 其中&#xff0c;S(j,K)表示与物品j最相似的K个物品&#xff0c;N(u)表示用户u喜欢的物品集合&#xff0c;Rui表示用户u对物品i的评分。 二、代码 public class ItemCFRecommendApp {public static void main(String[]args){SparkConf sparkConf new …

jzoj6308-中间值【分治】

正题 题目大意 两个序列不降a,ba,ba,b&#xff0c;每次可以修改或询问[l1,r1,l2,r2][l_1,r_1,l_2,r_2][l1​,r1​,l2​,r2​]要求输出将序列aaa的l1∼r1l_1\sim r_1l1​∼r1​和bbb的l2∼r2l_2\sim r_2l2​∼r2​部分合起来然后求中位数。 解题思路 我们考虑分治&#xff0c;…

ASP.NET Core Razor 页面使用教程

ASP.NET Core Razor 页面作为 ASP.NET Core 2.0的一部分发布&#xff0c;它是基于页面的全新的Web开发框架。如果您想学习如何使用 ASP.NET Core Razor 页面&#xff0c;可以访问微软的官方站点https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/razor-page…

如何面试.NET/ASP.NET工程师?

2018-2-28 更新&#xff1a;距离这篇回答发布已经五年过去了&#xff0c;最近还经常受到关注。技术本身在发展&#xff0c;这令我感到有必要来更新一下&#xff0c;希望对新看到的朋友有用。对于服务器上的 .NET 技术&#xff0c;最新的发展当然是 .NET Core 了&#xff0c;作为…

欢乐纪中A组赛【2019.8.18】

前言 有一个暴力写挂了QVQQVQQVQ 成绩 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC111111(J−3)LRZ(J-3)LRZ(J−3)LRZ140140140100100100303030101010191919(J−3)WYC(J-3)WYC(J−3)WYC120120120100100100101010101010262626(J−3)HZB(J-3)HZB(J−3)HZB100100100…

Asp.Net Core 2.1+的视图缓存(响应缓存)

响应缓存Razor 页与 ASP.NET 核心 2.0 中不支持。 此功能将支持ASP.NET 核心 2.1 版本。在老的版本的MVC里面&#xff0c;有一种可以缓存视图的特性(OutputCache)&#xff0c;可以保持同一个参数的请求&#xff0c;在N段时间内&#xff0c;直接从mvc的缓存中读取&#xff0c;不…

Json.NET 不再有超过120个依赖项

Json.NET是.NET的官方的JSON解析和序列化库&#xff0c;它取代了Microsoft实际提供的库。但是当把Json.NET推向.NET Standard时&#xff0c;出现了一些问题。除了在该平台上无法使用的众多方法之外&#xff0c;在NET Standard 1.3上的Json.NET需要高达122个依赖包。随着适用于.…

C#热度不如Java?网友呛声:还有使用C#不能完成的工作?

C#是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言&#xff0c;自发布以来受到了程序员的广泛关注。C#与Java有着很多相似之处&#xff0c;例如&#xff0c;单一继承、接口、与Java几乎同样的语法和编译成中间代码再运行的过程。但是与Java每月被…

EntityFramework Core 2.0执行原始查询如何防止SQL注入?

前言接下来一段时间我们来讲讲EntityFramework Core基础&#xff0c;精简的内容&#xff0c;深入浅出&#xff0c;希望为想学习EntityFramework Core的童鞋提供一点帮助。EntityFramework Core执行原始查询在EntityFramework Core中执行原始查询我们借助FromSql来实现&#xff…

EntityFramework Core 2.0自定义标量函数两种方式

前言上一节我们讲完原始查询如何防止SQL注入问题同时并提供了几种方式。本节我们继续来讲讲EF Core 2.0中的新特性自定义标量函数。自定义标量函数两种方式在EF Core 2.0中我们可以将方法映射到数据库中的标量函数&#xff0c;我们可在LINQ中调用此方法并会被正确翻译成SQL语句…

ASP.NET Core远程调试

关于ASP.NET Core远程调试的具体做法可参考微软文档——Remote Debug ASP.NET Core on a Remote IIS Computer in Visual Studio 2017&#xff0c;详细做法不再赘述&#xff0c;这里主要记录下自己的感受。体验Web Deploy这种发布方式可直接将代码打包发到指定服务器的指定站点…

修复.NET的HttpClient

早在2016年我们就报道过 &#xff0c;.NET的HttpClient存在一些问题。随着.NET Core 2.1中HttpClientFactory的引入&#xff0c;其中部分问题已经得到缓解。HttpClient的根本问题是&#xff0c;每次调用资源好像都应该在使用后立即释放。在现实中&#xff0c;那意味着每个目标服…

欢乐纪中A组赛【2019.8.20】

前言 Rank1???Rank1???Rank1??? 成绩 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC111(J−3)WYC(J-3)WYC(J−3)WYC145145145100100100000454545212121(J−3)ZYC(J-3)ZYC(J−3)ZYC636363383838000252525353535(J−3)XXY(J-3)XXY(J−3)XXY45454500000045454…

Asp.Net Core2.0 基于QuartzNet任务管理系统

Quartz.NET官网地址&#xff1a;https://www.quartz-scheduler.net/Quartz.NET文档地址&#xff1a;https://www.quartz-scheduler.net/documentation/index.htmlQuartz.NET是一个开源的作业调度框架&#xff0c;是OpenSymphony 的 Quartz API的.NET移植&#xff0c;它用C#写成…

64位的Mac OS X也有Windows.Forms了

Mono长期以来一直为Linux、Mac和Windows提供Windows.Forms的纯C#实现。随着技术潮流的变化&#xff0c;Mono的Windows.Forms平台仍然没有得到很好的发展&#xff0c;还只是各种第三方库和应用程序的依赖&#xff0c;这使得它的重要性超过了那些基于WinForms的应用程序。Mono默认…

.Net 4.X 提前用上 .Net Core 的配置模式以及热重载配置

1. 前言在提倡微服务及 Serverless 越来越普及的当下&#xff0c;传统 .Net 应用的配置模式往往依赖于一个名为 web.config 的 XML 文件&#xff0c;在可扩展性和可读性与时代脱节了。当然&#xff0c;我不会怂恿一下子把所有应用迁移到 .Net Core 上&#xff0c;本文将在尽量不…

C# 枚举特性 FlagAttribute 的应用

写在前面枚举Enum 全称(Enumeration)&#xff0c;即一种由一组称为枚举数列表的命名常量组成的独特类型。可以看出枚举的出现是为了使我们可以在程序中方便的使用一些特定值的常量&#xff0c;一般的使用大家都比较熟悉&#xff0c;本文主要介绍枚举的特性 FlagAttribute。Flag…