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

ASP.NET 8升级后DTO枚举在OpenAPI中被生成为字符串的问题求助

解决ASP.NET 8.0中NSwag生成FromForm枚举为Integer类型的问题

方案一:自定义ApiDescriptionProvider修正类型描述

ASP.NET 8.0的DefaultApiDescriptionProvider会将FromForm中的枚举识别为string类型,我们可以继承并重写该类,强制将FromForm参数里的枚举类型修正为integer:

public class CustomApiDescriptionProvider : DefaultApiDescriptionProvider
{
    public CustomApiDescriptionProvider(IApiDescriptionProviderOptions options, IModelMetadataProvider modelMetadataProvider, IHttpMethodMetadataProvider httpMethodMetadataProvider, IEnumerable<IApiParameterDescriptionProvider> parameterDescriptionProviders)
        : base(options, modelMetadataProvider, httpMethodMetadataProvider, parameterDescriptionProviders)
    {
    }

    protected override ApiDescription CreateResult(ActionDescriptor actionDescriptor, ApiDescriptionProviderContext context)
    {
        var apiDescription = base.CreateResult(actionDescriptor, context);

        // 遍历所有参数,修正FromForm中的枚举类型
        foreach (var paramDesc in apiDescription.ParameterDescriptions)
        {
            if (paramDesc.Source is FormBindingSource && paramDesc.Type.IsEnum)
            {
                // 将参数类型设为int
                paramDesc.Type = typeof(int);
                // 手动添加枚举值和名称到扩展属性,保证NSwag能生成enum和x-enumNames
                paramDesc.Extensions["enum"] = Enum.GetValues(paramDesc.Type).Cast<int>().ToArray();
                paramDesc.Extensions["x-enumNames"] = Enum.GetNames(paramDesc.Type);
            }
        }

        return apiDescription;
    }
}

然后在Program.cs中替换默认服务:

builder.Services.Replace(ServiceDescriptor.Transient<IApiDescriptionProvider, CustomApiDescriptionProvider>());

方案二:NSwag自定义Schema处理器

直接在NSwag的Schema生成阶段干预,将FromForm对应的枚举Schema强制设为integer类型:

builder.Services.AddOpenApiDocument(config =>
{
    config.SchemaGenerator.SchemaProcessors.Add(new EnumAsIntegerFormSchemaProcessor());
});

public class EnumAsIntegerFormSchemaProcessor : ISchemaProcessor
{
    public void Process(SchemaProcessorContext context)
    {
        // 仅处理FromForm参数中的枚举属性
        if (context.ContextualType.OriginalType.IsEnum && 
            context.Parameter?.Source is FormBindingSource)
        {
            context.Schema.Type = "integer";
            context.Schema.Format = "int32";
            // 填充枚举值和名称
            context.Schema.Enum = Enum.GetValues(context.ContextualType.OriginalType)
                .Cast<int>()
                .Select(v => (object)v)
                .ToList();
            context.Schema.Extensions["x-enumNames"] = Enum.GetNames(context.ContextualType.OriginalType);
        }
    }
}

方案三:属性级别的强制绑定配置

在DTO的枚举属性上添加特性,明确指定枚举的绑定行为:

public class FileUploadDto
{
    public IFormFile File { get; set; }

    [BindProperty]
    [EnumDataType(typeof(FileType))]
    public FileType Type { get; set; }
}

同时在Program.cs中添加元数据提供器:

builder.Services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new EnumDataTypeModelMetadataProvider());
});

这个方案适合只需要修正个别枚举属性的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 01:43:32