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/
问题是 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/