自动将 URL 查询参数键转换为短横线大小写?

Mar*_*ese 5 c# asp.net-core-mvc asp.net-core

ASP.NET 默认使用PascalCase URL 组件,但我想改用短横线大小写。我已经看到各种文章SO 答案通过RouteTokenTransformerConvention(下面的示例代码)在 ASP.NET Core 中优雅地实现了这一点。我喜欢这个策略,因为它 1) 确保 kebab-case 路由映射到正确的控制器,并使用正确的路由参数执行操作,而无需重复的手动工作;2) 允许您生成匹配的 kebab-case 链接。

但是,它不涉及 URL 查询。 有没有办法既能获得上述好处,又能在转换中包含查询键? 例如:

  • 我想要一个像这样的网址:some-route?product-category=some+product+category...
  • ProductCategory将绑定模型的属性设置为"some product category"
    • (无需我装饰或使用这个稍微好一点的ProductCategory想法使用其他一些手动解决方案)[FromQuery(Name="product-category")]
  • 查询不应被转换——仅转换

这是我从上述链接中获取的代码作为起点:

连字符.cs

using Microsoft.AspNetCore.Routing;
using System.Text.RegularExpressions;

public class Hyphenator: IOutboundParameterTransformer
{
    public string TransformOutbound(object value)
    {
        if (value == null) 
        { 
            return null; 
        }
        return Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower();
    }
}
Run Code Online (Sandbox Code Playgroud)

启动.cs

services.AddControllersWithViews(options =>
{
    options.Conventions.Add(new RouteTokenTransformerConvention(new Hyphenator()));
});
Run Code Online (Sandbox Code Playgroud)

编辑以澄清:

我希望有一个解决方案能够在出站方向上进行转换(如上面的示例代码),这样除了模型绑定工作之外,我还可以将常规 PascalCase 属性名称传递给生成 URL 的代码(例如锚标记帮助程序和方法,例如RedirectToRoute()),并且这些 URL 中的查询键最终在用户的浏览器中采用短横线形式。这可能吗?

pei*_*ent 2

我认为字符串操作代码可以提高一些效率。这是一个概念证明。您可以创建一个 url 重写器规则来操作传入的查询字符串。

public class MyRule : IRule
{
    public void ApplyRule(RewriteContext context)
    {
        Dictionary<string, StringValues> newQueryCollection = context.HttpContext.Request.Query.ToDictionary(
            kv => ToPascalCase(kv.Key),
            kv => kv.Value
        );

        context.HttpContext.Request.Query = new QueryCollection(newQueryCollection);
    }

    private static string ToPascalCase(string kebabCase)
    {
        return string.Join(string.Empty, kebabCase.Split('-').Select(str => str.Length > 0 ? char.ToUpper(str[0]) + str.Substring(1) : str));
    }
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    var options = new RewriteOptions().Add(new MyRule());
    app.UseRewriter(options);
    app.UseRouting();

    /*
        register other app builder extensions after this point
    */
}
Run Code Online (Sandbox Code Playgroud)

如果重写发生在管道的早期,即在 mvc 中间件运行之前,则查询字符串参数的更新键应该用于绑定模型。