You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swashbuckle为何不遵循ASP.Net Core API的snake_case命名规则?

解决Swashbuckle中[FromForm]模型参数无法转为snake_case的问题

对于ASP.Net Core API中使用[FromForm]的multipart/form-data请求,Swashbuckle默认不会应用全局的snake_case命名策略,需要通过自定义IOperationFilter专门处理表单参数的名称转换。

实现步骤

1. 自定义表单参数转snake_case的OperationFilter

创建如下类,遍历并转换multipart/form-data类型请求的所有表单参数名称:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Text.RegularExpressions;

public class FormDataSnakeCaseOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 定位到multipart/form-data类型的请求体
        var formDataMediaType = operation.RequestBody?.Content
            .FirstOrDefault(c => c.Key.Equals("multipart/form-data", StringComparison.OrdinalIgnoreCase))
            .Value;
        
        if (formDataMediaType == null) return;

        // 转换所有属性名为snake_case
        var convertedProps = new Dictionary<string, OpenApiSchema>();
        foreach (var prop in formDataMediaType.Schema.Properties)
        {
            var snakeCaseName = ConvertToSnakeCase(prop.Key);
            convertedProps[snakeCaseName] = prop.Value;

            // 同步更新示例值的键名
            if (formDataMediaType.Example is OpenApiObject exampleObj && exampleObj.ContainsKey(prop.Key))
            {
                var value = exampleObj[prop.Key];
                exampleObj.Remove(prop.Key);
                exampleObj[snakeCaseName] = value;
            }
        }

        // 替换原有属性集合
        formDataMediaType.Schema.Properties.Clear();
        foreach (var prop in convertedProps)
        {
            formDataMediaType.Schema.Properties.Add(prop.Key, prop.Value);
        }

        // 同步更新必填字段的键名
        if (formDataMediaType.Schema.Required?.Any() == true)
        {
            var requiredFields = formDataMediaType.Schema.Required.ToList();
            formDataMediaType.Schema.Required.Clear();
            foreach (var field in requiredFields)
            {
                formDataMediaType.Schema.Required.Add(ConvertToSnakeCase(field));
            }
        }
    }

    // PascalCase转snake_case的工具方法
    private string ConvertToSnakeCase(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;
        return Regex.Replace(input, @"([a-z0-9])([A-Z])", "$1_$2").ToLower();
    }
}

2. 注册自定义Filter

在Program.cs的Swagger配置中添加这个Filter:

builder.Services.AddSwaggerGen(c =>
{
    // 其他Swagger配置项...
    
    // 注册表单参数转snake_case的Filter
    c.OperationFilter<FormDataSnakeCaseOperationFilter>();
});

说明

之前使用普通IOperationFilter操作operation.Parameters无效的原因:multipart/form-data的模型参数会被Swashbuckle展开到RequestBody.Content["multipart/form-data"].Schema.Properties中,而非直接作为operation.Parameters的成员,因此需要针对性处理请求体内部的属性集合。

内容的提问来源于stack exchange,提问作者ataraxia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:57:42