.Net Core NSwag生成multipart/form-data文档未识别必填字段问题
问题根因
NSwag默认对multipart/form-data类型请求的schema生成逻辑和JSON请求体不同,不会自动读取模型属性上的[Required]特性填充必填字段列表;同时未开启可空引用类型(NRT)的项目中,string这类引用类型会被默认判定为可空,最终出现字符串字段标记nullable:true、必填列表缺失的问题,直接导致下游生成的TS接口属性可选。
修复方案
按优先级从高到低选择以下方案即可:
方案1:全局配置适配(推荐,无侵入)
- 第一步:在项目
.csproj文件中开启可空引用类型支持,让编译器自动识别非可空引用类型:
<PropertyGroup> <Nullable>enable</Nullable> </PropertyGroup>
开启后,未显式加?后缀的string类型属性会被识别为非可空,DateTime这类值类型本身默认不可空,不需要额外处理。
- 第二步:在服务配置阶段(Program.cs/Startup.cs)修改NSwag默认规则,开启必填项自动识别:
builder.Services.AddOpenApiDocument(config => { // 自动将标记[Required]的属性加入schema必填列表 config.RequireParametersWithoutDefault = true; // 根据可空引用类型信息自动标记字段是否可空 config.SchemaSettings.GenerateNullableReferenceTypes = true; });
如果项目暂时无法全量开启可空引用类型,直接给带[Required]的字符串属性叠加[DisallowNull]特性,也能让NSwag识别为非可空字段。
方案2:自定义Schema处理器(适配form-data特殊场景)
如果全局配置开启后,multipart/form-data场景下规则仍未生效,可添加自定义处理器强制补全schema规则:
- 实现
ISchemaProcessor接口,针对form-data请求遍历属性补全必填标记:
public class FormDataRequiredSchemaProcessor : ISchemaProcessor { public void Process(SchemaProcessorContext context) { // 仅处理multipart/form-data类型的请求模型 if (!context.RequestIsFormData()) return; var requiredPropNames = context.ContextualType.Properties .Where(prop => prop.Attributes.OfType<RequiredAttribute>().Any()) .Select(prop => prop.Name) .ToList(); if (!requiredPropNames.Any()) return; context.Schema.Required ??= new List<string>(); foreach (var propName in requiredPropNames) { if (!context.Schema.Required.Contains(propName)) context.Schema.Required.Add(propName); // 移除字符串属性错误的nullable标记 if (context.Schema.Properties.TryGetValue(propName, out var propSchema) && propSchema.Type == JsonObjectType.String) { propSchema.IsNullable = false; } } } }
- 在NSwag配置中注册自定义处理器:
builder.Services.AddOpenApiDocument(config => { config.SchemaSettings.SchemaProcessors.Add(new FormDataRequiredSchemaProcessor()); });
方案3:单属性显式标记(临时修复用)
如果不需要修改全局配置,可直接在对应模型属性上用NSwag自带的特性显式声明属性规则:
[Required] [OpenApiProperty(IsNullable = false, IsRequired = true)] public string Name { get; set; } [Required] [OpenApiProperty(IsNullable = false, IsRequired = true)] public string Abbreviation { get; set; } [Required] public DateTime DateOfFundation { get; set; }
该方案需要逐个给属性加特性,仅适合字段量少的临时修复场景。
验证方式
重新编译项目生成swagger.json,对应multipart/form-data节点的schema会新增required数组列出所有必填字段,字符串类型字段的nullable:true标记会被移除,基于该schema生成的TypeScript接口就不会把必填属性错误设置为可选。
内容的提问来源于stack exchange,提问作者PkDev
相关产品推荐
相关产品推荐

