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

NSwag生成的Angular客户端向.NET Core传文件失败求助

.NET Core 6 + Angular NSwag 文件上传问题解决指引

问题场景

后端基于.NET Core 6开发,控制器通过[FromForm]接收包含IFormFile的模型,接口在Swagger UI中可正常调用,但NSwag生成的Angular客户端调用时抛出错误:FormData.append: Argument 2 is not an object。

相关代码

后端控制器代码

[HttpPost("single-file"), DisableRequestSizeLimit]
public async Task<ActionResult<int>> Create([FromForm] CreateUploadedDocumentModel model)
{
    // 业务逻辑实现
}

前端文件选择组件

<input (change)="selectFiles($event)" class="form-control" type="file" id="formFileMultiple">

前端调用客户端代码

this.uploadClient.create(1, file, file.name).subscribe(
  result => {
    console.log(result);
  },
  err => {
    this.message = 'Could not upload the file:' + file.name;
  });

NSwag生成的客户端代码片段

create(consultantId: number | undefined, file: FileParameter | null | undefined, fileName: string | null | undefined): Observable<number> {
    let url_ = this.baseUrl + "/api/UploadedDocuments/single-file";
    url_ = url_.replace(/[?&]$/, "");

    const content_ = new FormData();
    if (consultantId === null || consultantId === undefined)
        throw new Error("The parameter 'consultantId' cannot be null.");
    else
        content_.append("ConsultantId", consultantId.toString());
    if (file !== null && file !== undefined)
        content_.append("File", file.data, file.fileName ? file.fileName : "File");
    if (fileName !== null && fileName !== undefined)
        content_.append("FileName", fileName.toString());
    // 后续请求逻辑
}

问题原因

NSwag生成的客户端方法期望接收FileParameter类型参数,但前端直接传入了原生File对象,导致客户端代码访问file.data时出现未定义的情况,触发FormData参数错误。

解决方案

1. 手动包装File对象为FileParameter

在调用客户端方法前,将原生File对象包装成客户端要求的FileParameter类型:

// 定义FileParameter结构(若生成代码未自动包含)
interface FileParameter {
  data: File;
  fileName?: string;
}

// 文件选择后的处理逻辑
selectFiles(event: Event) {
  const fileList = (event.target as HTMLInputElement).files;
  if (fileList) {
    Array.from(fileList).forEach(file => {
      // 包装成符合要求的FileParameter
      const fileParam: FileParameter = {
        data: file,
        fileName: file.name
      };
      // 调用客户端上传方法
      this.uploadClient.create(1, fileParam, file.name).subscribe(
        result => console.log(result),
        err => this.message = `Could not upload the file: ${file.name}`
      );
    });
  }
}

2. 优化NSwag生成配置(避免手动包装)

调整NSwag生成配置,让客户端直接支持原生File类型传入:

  • 在nswag.json中添加或修改以下配置:
    {
      "runtime": "Net60",
      "documentGenerator": {
        "aspNetCoreToOpenApi": {
          "operationNameGenerator": "AspNetCoreOperationNameGenerator",
          "output": "swagger.json"
        }
      },
      "codeGenerator": {
        "angular": {
          "generateClientClasses": true,
          "generateClientInterfaces": false,
          "formDataToClass": true,
          "generateHttpClientType": true,
          "useTransformOptionsMethod": true,
          "useGetBaseUrlMethod": true,
          "className": "{controller}Client",
          "moduleName": "App",
          "output": "src/app/api-client.ts"
        }
      }
    }
    
  • 重新生成客户端代码后,方法将直接支持传入原生File对象,无需手动包装。

3. 校验后端模型属性名

确保CreateUploadedDocumentModel的属性名与客户端FormData的键名完全匹配:

public class CreateUploadedDocumentModel
{
    public int ConsultantId { get; set; }
    public IFormFile File { get; set; }
    public string? FileName { get; set; }
}

属性名需与客户端代码中content_.append的键名(如"ConsultantId"、"File")一致,避免因名称不匹配导致参数绑定失败。


内容的提问来源于stack exchange,提问作者Kasper Sölvström

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:25:20