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

Minimal APIs单请求表单提交上传文件遇LegalEntity缺失错误

错误原因分析
  1. 请求格式与接收方式不匹配:端点使用[FromForm]标记接收表单数据,但当前请求发送的是application/json格式负载。ASP.NET Core无法将JSON自动绑定到表单模型,导致LegalEntity属性无法被正确解析,触发必填字段缺失的异常。
  2. 嵌套对象的表单绑定规则:即使改用multipart/form-data格式,嵌套的LegalEntityDto对象无法直接通过JSON对象提交,需要遵循表单绑定的命名规则(如用点符号拆分嵌套字段,或提交JSON字符串并配置模型绑定支持反序列化)。
  3. 文件集合的提交要求:IFormFileCollection需要在multipart/form-data请求中作为独立的文件字段上传,而非嵌入在JSON payload内。
解决方案

方案一:调整请求为multipart/form-data格式(推荐)

1. 修改请求构造方式

将请求的Content-Type设为multipart/form-data,包含以下两部分内容:

  • 一个名为LegalEntity的文本字段,值为原JSON中legalEntity对象的JSON字符串(注意转义特殊字符)。
  • 多个文件字段(对应Documents集合),字段名统一设为Documents(ASP.NET Core会自动绑定到IFormFileCollection)。

示例curl请求:

curl -X POST https://your-api/legalentities \
  -H "Content-Type: multipart/form-data" \
  -F "LegalEntity={\"name\":\"Acme Corporation\",\"shortName\":\"Acme Corp\",\"type\":\"Organization\",\"registrationNumber\":\"REG123456\",\"dateOfIncorporation\":\"2000-01-01T00:00:00\",\"taxIdentificationNumber\":\"TAX987654\",\"country\":\"United States\",\"industryType\":\"Technology\",\"creditLimit\":1000000.00,\"contactInformation\":{\"primaryContactName\":\"John Doe\",\"primaryContactPhoneNumber\":\"+1 (555) 123-4567\",\"primaryContactEmail\":\"john.doe@acmecorp.com\",\"secondaryContactName\":\"Jane Smith\",\"secondaryContactPhoneNumber\":\"+1 (555) 987-6543\",\"secondaryContactEmail\":\"jane.smith@acmecorp.com\",\"website\":\"https://www.acmecorp.com\"},\"addressInformation\":{\"street\":\"123 Tech Street\",\"city\":\"Silicon Valley\",\"state\":\"CA\",\"postalCode\":\"94000\"},\"bankInformation\":{\"accountName\":\"Acme Corporation Operating Account\",\"accountNumber\":\"1234567890\",\"swiftCode\":\"TECHUS123\",\"iban\":\"DE89370400440532013000\",\"bankAddress\":\"456 Bank Street, Silicon Valley, CA 94000, USA\"},\"kycInformation\":{\"status\":\"Pending\",\"riskRating\":\"Low\",\"amlStatus\":\"Compliant\",\"sanctionsCheckStatus\":\"Passed\",\"complianceNotes\":\"Initial compliance review completed\",\"parentCompany\":null,\"documents\":[{\"documentType\":\"Certificate of Incorporation\",\"documentName\":\"acme_incorporation.pdf\",\"documentDescription\":\"Certificate of Incorporation for Acme Corp\"}]},\"uboInformation\":{\"name\":\"John Doe\",\"ownershipPercentage\":100.00,\"nationality\":\"United States\",\"identificationNumber\":\"123-45-6789\"}}" \
  -F "Documents=@acme_incorporation.pdf"

2. 调整命令类的模型绑定配置

在CreateLegalEntityCommand的属性上添加[FromForm]标记,明确绑定来源:

public sealed record CreateLegalEntityCommand : IRequest<Result<Guid>>
{
    [FromForm]
    public required LegalEntityDto LegalEntity { get; init; }
    
    [FromForm]
    public required IFormFileCollection Documents { get; init; }
}

3. 配置表单JSON反序列化支持(可选)

如果嵌套对象反序列化失败,在Program.cs中添加配置,让模型绑定支持从表单字符串反序列化JSON对象:

builder.Services.AddControllers(options =>
{
    options.ModelBinderProviders.Insert(0, new FormJsonModelBinderProvider());
});

方案二:自定义混合绑定逻辑

如果需要更灵活的绑定方式,可自定义模型绑定逻辑:

  1. 修改命令类,添加静态绑定方法:
public sealed record CreateLegalEntityCommand : IRequest<Result<Guid>>
{
    public LegalEntityDto LegalEntity { get; set; }
    public required IFormFileCollection Documents { get; init; }

    public static async ValueTask<CreateLegalEntityCommand?> BindAsync(HttpContext context, ParameterInfo parameter)
    {
        var form = await context.Request.ReadFormAsync();
        var legalEntityJson = form["LegalEntity"].FirstOrDefault();
        var legalEntity = JsonSerializer.Deserialize<LegalEntityDto>(legalEntityJson);
        
        return new CreateLegalEntityCommand
        {
            LegalEntity = legalEntity,
            Documents = form.Files
        };
    }
}
  1. 移除端点中的[FromForm]标记,框架会自动调用自定义绑定方法。
验证要点
  • 确认请求Content-Type为multipart/form-data,而非application/json。
  • 检查LegalEntity字段的JSON字符串格式正确,无语法错误。
  • 确保至少上传一个文件,满足Documents的必填要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:32:06