I have tried the solution here: How to properly set up snake case JSON for dotnet core api? but seems to be this is only for request/response payloads. Is there a way to force snake_case format on my [FromQuery] parameters?
Currently this is what I have as of the moment

What you did is about json serialization in asp.net core but what you want is to change the Swagger UI. They are the quite different things.
The first way, you can add attribute like: [FromQuery(Name = "account_number")].
Or you can custom an attribute to avoid writing snake_case:
public class CustomFromQueryAttribute : FromQueryAttribute
{
public CustomFromQueryAttribute(string name)
{
Name = name.ToSnakeCase();
}
}
Custom ToSnakeCase for string extension:
public static class StringExtensions
{
public static string ToSnakeCase(this string o) =>
Regex.Replace(o, @"(\w)([A-Z])", "$1_$2").ToLower();
}
Usage:
public voidGet([CustomFromQuery("AccountNumber")]string AccountNumber)
Note:
Actually this way equals to using public voidGet(string account_number), so the Swagger UI changed.
The second way, you can custom IOperationFilter like below to change the Swagger UI:
public class SnakecasingParameOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null) operation.Parameters = new List<OpenApiParameter>();
else {
foreach(var item in operation.Parameters)
{
item.Name = item.Name.ToSnakeCase();
}
}
}
}
Register the service like below:
services.AddSwaggerGen(c =>
{
c.OperationFilter<SnakecasingParameOperationFilter>();
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApi5_0", Version = "v1" });
});
But this way change the request query string to snake case which has an extra _, It does not match the backend parameter. So you also need to custom value provider that looks for snake cased query parameters:
SnakeCaseQueryValueProvider:
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());
}
}
We also have to implement a factory for our value provider:
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;
}
}
Register the services:
services.AddControllers(options =>
{
options.ValueProviderFactories.Add(new SnakeCaseQueryValueProviderFactory()); //add this...
}).AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With