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
相关产品推荐
相关产品推荐

