I have an ASP.Net Core API with Swagger and Swashbuckle code attributes to generate documentation for the UI. The API's naming policy is snake_case throughout, which on most of the documentation is fine, however where I have a data model being used in an endpoint method which has the [FromForm] attribute, i.e. it's uploaded as multipart/form-data, Swagger/Swashbuckle just WILL NOT convert the casing:
The Swashbuckle documentation is useless, I've tried ISchemaFilter, IOperationFilter and IDocumentFilter and can't find anything, I've also asked Github Copilot and that has no idea what it's doing either, it keeps telling me to use an IOperationFilter to set the operation parameter names, which I'm already doing and that's not working.
How do I do this? All I want is the following:
You can use IOperationFilter like below. And please check test result first.
SnakeCaseRequestBodyFilter.cs
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Text.RegularExpressions;
namespace WebApplication2
{
public class SnakeCaseRequestBodyFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
Regex regex = new Regex("([a-z])([A-Z])");
foreach (var parameter in operation.Parameters.Where(p => p.In == ParameterLocation.Query || p.In == ParameterLocation.Header || p.In == ParameterLocation.Path || p.In == ParameterLocation.Cookie))
{
parameter.Name = regex.Replace(parameter.Name, "$1_$2").ToLower();
}
if (operation.RequestBody != null && operation.RequestBody.Content.ContainsKey("multipart/form-data"))
{
var formDataContent = operation.RequestBody.Content["multipart/form-data"];
if (formDataContent.Schema?.Properties != null)
{
var properties = formDataContent.Schema.Properties;
foreach (var prop in properties.Keys.ToList())
{
var snakeCaseKey = regex.Replace(prop, "$1_$2").ToLower();
if (snakeCaseKey != prop)
{
var schema = properties[prop];
properties.Remove(prop);
properties[snakeCaseKey] = schema;
}
}
}
}
}
}
}
Register it.
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
c.OperationFilter<SnakeCaseRequestBodyFilter>();
});