• 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/
  • 相关阅读:
    招聘、外包和求职;找人、找活和找工作的都来看看。
    这周我加星(6)
    走出行业暴利思维,开始为“软件”付钱!
    真相,道歉。
    这周我加星(8-11)
    独家:Havok 发布新的 AI 中间件
    一奖三年得,终获 CSDN MVB,与大家分享喜悦
    “解决”OpenCASCADE图形设备初始化问题
    如何在Debian上安装ATI官方驱动
    VC++/MFC学习笔记(六)
  • 原文地址:https://www.cnblogs.com/Soar1991/p/8487213.html
Copyright © 2020-2023  润新知