SnakeCase 查询参数 .Net Core

SnakeCase QueryParams .Net Core

问题是 QueryParams 对象不是 snake case

        public async Task<IActionResult> Search (
        [FromQuery] ProjectFilterDto filterParams,
        [FromQuery(Name = "page_size")] int pageSize = 10,
        [FromQuery(Name = "page_index")] int pageIndex = 0)

所有其他的东西,FromBody 和 Response 都是蛇形语法

启动;

options.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
  NamingStrategy = new SnakeCaseNamingStrategy(true, true)
};

有没有什么方法可以在不使用 FromQuery(Name="x") 的情况下使 ProjectFilterDto 之类的查询参数成为 snake case?

首先创建一个扩展方法,将给定的字符串转换为它的蛇形版本。我们在下一步中将需要这个方法。

public static string ToSnakeCase(this string s)
{
    if (string.IsNullOrWhiteSpace(s))
    {
        return s;
    }

    s = s.Trim();

    var length = s.Length;
    var addedByLower = false;
    var stringBuilder = new StringBuilder();

    for (var i = 0; i < length; i++)
    {
        var currentChar = s[i];

        if (char.IsWhiteSpace(currentChar))
        {
            continue;
        }

        if (currentChar.Equals('_'))
        {
            stringBuilder.Append('_');
            continue;
        }

        bool isLastChar = i + 1 == length,
                isFirstChar = i == 0,
                nextIsUpper = false,
                nextIsLower = false;

        if (!isLastChar)
        {
            nextIsUpper = char.IsUpper(s[i + 1]);                    
            nextIsLower = !nextIsUpper && !s[i + 1].Equals('_');
        }

        if (!char.IsUpper(currentChar))
        {
            stringBuilder.Append(char.ToLowerInvariant(currentChar));

            if (nextIsUpper)
            {
                stringBuilder.Append('_');
                addedByLower = true;
            }

            continue;
        }

        if (nextIsLower && !addedByLower && !isFirstChar)
        {
            stringBuilder.Append('_');
        }

        addedByLower = false;

        stringBuilder.Append(char.ToLowerInvariant(currentChar));
    }

    return stringBuilder.ToString();
}

现在我们可以创建一个自定义值提供程序,它使用上面定义的 ToSnakeCase() 扩展方法查找蛇形查询参数。

public class SnakeCaseQueryValueProvider : QueryStringValueProvider, IValueProvider
{
    public SnakeCaseQueryValueProvider(
        BindingSource bindingSource, 
        IQueryCollection values, 
        CultureInfo culture) 
        : base(bindingSource, values, culture)
    {
    }

    public override bool ContainsPrefix(string prefix)
    {
        return base.ContainsPrefix(prefix.ToSnakeCase());
    }

    public override ValueProviderResult GetValue(string key)
    {
        return base.GetValue(key.ToSnakeCase());
    }
}

我们还必须为我们的值提供者实现一个工厂:

public class SnakeCaseQueryValueProviderFactory : IValueProviderFactory
{
    public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var valueProvider = new SnakeCaseQueryValueProvider(
            BindingSource.Query,
            context.ActionContext.HttpContext.Request.Query,
            CultureInfo.CurrentCulture);

        context.ValueProviders.Add(valueProvider);

        return Task.CompletedTask;
    }
}

唯一剩下要做的就是在 Startup class 的 ConfigureServices 方法中注册值提供程序。

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc(options =>
        {
            options.ValueProviderFactories.Add(new SnakeCaseQueryValueProviderFactory());
        }) 
        .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver
        {
            NamingStrategy = new SnakeCaseNamingStrategy()
        });
}

希望对您有所帮助!

我在这里写了一篇博客 post:http://www.sorting.se/enable-snake-cased-query-parameters-in-your-restfull-asp-net-core-web-api/