zoukankan      html  css  js  c++  java
  • ASP.NET Core如何自动生成小写的破折号路由

    默认情况下,ASP.NET Core使用如 http://localhost:5000/HomeIndex 类的大驼峰路由。但是如果想使用小写的路由,并且这些路由用破折号分隔:http://localhost:5000/home-index它们比较常见且一致。

    举例.NET常见路由
    http://localhost:5000/User/ListPages
    想要的效果
    http://localhost:5000/user/list-pages

    1、如何生成小写的路由可以这样设置

    services.ConfigureRouting(setupAction => {
        setupAction.LowercaseUrls = true;
    });

    2、生成带破折号并且小写的路由可以这样设置

    [Route("dashboard-settings")]
    class DashboardSettings:Controller {
        public IActionResult Index() {
            // ...
        }
    }

    似乎上面使用特性路由可以解决这个问题。但是我不想使用,因为每个action都要手动去设置,太繁琐也很容易出错。

    我想要的效果是在程序中写个扩展类做到可配置处理。

    3、解决方案

    以下支持Asp.Net Core Version>=2.2

    要做到这一点,首先创建SlugifyParameterTransformer类应该如下所示

    public class SlugifyParameterTransformer : IOutboundParameterTransformer
    {
        public string TransformOutbound(object value)
        {
            // Slugify value
            return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower();
        }
    }

    3.1 对于Asp.Net Core2.2 MVC:

    在StartUp中ConfiregeServices这样配置

    services.AddRouting(option =>
    {
        option.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
    });

    路由如下配置:

    app.UseMvc(routes =>
    {
        routes.MapRoute(
           name: "default",
           template: "{controller:slugify}/{action:slugify}/{id?}",
           defaults: new { controller = "Home", action = "Index" });
     });

    3.2  对于Asp.Net Core2.2 Web API:

    在StartUp中ConfiregeServices这样配置

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options => 
        {
            options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    3.3 对于Asp.Net Core>=3.0 MVC:

    在StartUp中ConfiregeServices这样配置

    services.AddRouting(option =>
    {
        option.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
    });

    路由如下配置:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapAreaControllerRoute(
            name: "AdminAreaRoute",
            areaName: "Admin",
            pattern: "admin/{controller:slugify=Dashboard}/{action:slugify=Index}/{id:slugify?}");
    
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller:slugify}/{action:slugify}/{id:slugify?}",
            defaults: new { controller = "Home", action = "Index" });
    });

    3.4 对于Asp.Net Core>=3.0 Web API:

    在StartUp中ConfiregeServices这样配置

    services.AddControllers(options => 
    {
        options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
    });

    3.5 对于Asp.Net Core>=3.0 Razor Pages:

    在StartUp中ConfiregeServices这样配置

    services.AddRazorPages(options => 
    {
        options.Conventions.Add(new PageRouteTransformerConvention(new SlugifyParameterTransformer()));
    });

    这样会使/Sys/UserList路由变为/sys/user-list

    3.6 对于上面MVC项目,路由模板要调整很多,其实还可以通过实现IControllerModelConvention来实现。

    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 template = new StringBuilder();
    
                        if (controllerAction.Controller.ControllerName != "Home")
                        {
                            template.Append(PascalToKebabCase(controller.ControllerName));
                        }
    
                        if (controllerAction.ActionName != "Index")
                        {
                            template.Append("/" + PascalToKebabCase(controllerAction.ActionName));
                        }
    
                        selector.AttributeRouteModel = new AttributeRouteModel()
                        {
                            Template = template.ToString()
                        };
                    }
                }
            }
    
            public 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();
            }
    }

    在StartUp中ConfiregeServices这样配置

    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc(options => options.Conventions.Add(new DashedRoutingConvention()));
    }

    译文:https://stackoverflow.com/questions/40334515/automatically-generate-lowercase-dashed-routes-in-asp-net-core

    作者:课间一起牛

    出处:https://www.cnblogs.com/mhg215/

    声援博主:如果您觉得文章对您有帮助,请点击文章末尾的【关注我】吧!

    别忘记点击文章右下角的【推荐】支持一波。~~~///(^v^)\~~~ .

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    如果您有其他问题,也欢迎关注我下方的公众号,可以联系我一起交流切磋!

     B站: 课间一起牛的B站         知乎:课间一起牛的知乎

    码云:课间一起牛的码云      github:课间一起牛的github

  • 相关阅读:
    node 命令
    nodejs项目搭建
    linux 安装与配置
    GestureDetector
    activity切换效果
    hadoop
    phonegap 自定义插件
    自定义控件-属性自定义
    zxing demo
    select 语句的执行顺序
  • 原文地址:https://www.cnblogs.com/mhg215/p/14415475.html
Copyright © 2011-2022 走看看