如何上传数据+;从Angular到.net core Web Api的多个文件

如何上传数据+;从Angular到.net core Web Api的多个文件,angular,typescript,asp.net-core,nswag,Angular,Typescript,Asp.net Core,Nswag,我的服务器使用.Net Core 2.1.402 这是我的C#类: public类sampledetailsdo { 公共Guid Id{get;set;} 公共字符串文本{get;set;} 公共IEnumerable ImageUrls{get;set;} 公共图像集合{get;set;} } 这是我的控制器 [HttpPut] [Route("{id:guid}")] public async Task<IActionResult> UpdateAsync([FromRout

我的服务器使用.Net Core 2.1.402

这是我的C#类:

public类sampledetailsdo
{
公共Guid Id{get;set;}
公共字符串文本{get;set;}
公共IEnumerable ImageUrls{get;set;}
公共图像集合{get;set;}
}
这是我的控制器

[HttpPut]
[Route("{id:guid}")]
public async Task<IActionResult> UpdateAsync([FromRoute]Guid id, [FromForm] SampleDetailsDtodto)
{
    Console.WriteLine(dto.Text); 
    Console.WriteLine(dto.Images.Length);
    return OK();
}
[HttpPut]
[路由(“{id:guid}”)]
公共异步任务UpdateAsync([FromRoute]Guid id,[FromForm]SampleDetailsTodToTo)
{
Console.WriteLine(dto.Text);
Console.WriteLine(dto.Images.Length);
返回OK();
}
我使用nswag生成客户机服务,但当前存在上载多个文件的bug(),因此我扩展了更新方法来创建我的,下面是代码:

 public update(id: string, dto: SampleDetailsDto | null | undefined): Observable<SampleDetailsDto | null> {
    let url_ = this._baseUrl + "/api/v1/Sample/{id}";
    if (id === undefined || id === null)
      throw new Error("The parameter 'id' must be defined.");
    url_ = url_.replace("{id}", encodeURIComponent("" + id));
    url_ = url_.replace(/[?&]$/, "");

    let options_: any = {
      observe: "response",
      responseType: "blob",
      headers: new HttpHeaders({
        "Accept": "application/json"
      })
    };
    return _observableFrom(this.transformOptions(options_)).pipe(_observableMergeMap(transformedOptions_ => {
      return this._http.put<SampleDetailsDto>(url_,dto, transformedOptions_);
    })).pipe(_observableMergeMap((response_: any) => {
      return this.transformResult(url_, response_, (r) => this.processUpdate(<any>r));
    })).pipe(_observableCatch((response_: any) => {
      if (response_ instanceof HttpResponseBase) {
        try {
          return this.transformResult(url_, response_, (r) => this.processUpdate(<any>r));
        } catch (e) {
          return <Observable<SampleDetailsDto | null>><any>_observableThrow(e);
        }
      } else
        return <Observable<SampleDetailsDto | null>><any>_observableThrow(response_);
    }));
  }
公共更新(id:string,dto:SampleDetailsDto | null |未定义):可观察{
让url=this.\u baseUrl+“/api/v1/Sample/{id}”;
if(id==未定义| | id==空)
抛出新错误(“必须定义参数“id”);
url=url=url。替换(“{id}”,encodeURIComponent(“+id));
url=url。替换(/[?&]$/,“”);
让选项:任意={
观察:“回应”,
响应类型:“blob”,
标题:新的HttpHeaders({
“接受”:“应用程序/json”
})
};
返回_observeFrom(this.transformOptions(options)).pipe(_observedEmergMap(transformedOptions)=>{
返回此内容。\u http.put(url、dto、transformedOptions);
})).pipe(_observembergemap((响应:any)=>{
返回此.transformResult(url、响应(r)=>this.processUpdate(r));
})).pipe(_observeCatch((响应:任意)=>{
if(HttpResponseBase的响应实例){
试一试{
返回此.transformResult(url、响应(r)=>this.processUpdate(r));
}捕获(e){
返回(e);
}
}否则
返回ObservateThrow(响应ObservateThrow);
}));
}
我想同时上传多个文件和数据,在这种情况下,所有图像都链接到SampleDetailsTo。但我们也可以想象这种情况:

public class SampleDetailsDto
{
    public Guid Id{ get; set; }
    public string Text { get; set; }
    public IEnumerable<ChildSampleDetailsDto> Children{ get; set; }
}

public class ChildSampleDetailsDto
{
    public Guid Id{ get; set; }
    public string Text { get; set; }
    public IEnumerable<string> ImageUrls { get; set; }
    public IFormCollection Images { get; set; }
}
public类sampledetailsdo
{
公共Guid Id{get;set;}
公共字符串文本{get;set;}
公共IEnumerable子项{get;set;}
}
公共类ChildSampleDetailsTo
{
公共Guid Id{get;set;}
公共字符串文本{get;set;}
公共IEnumerable ImageUrls{get;set;}
公共图像集合{get;set;}
}
是否可以将数据+多个文件发送到.net核心Web Api


谢谢

阅读maherjendoubi的答案这里:


使用
ifformfile
[FromForm]
并且不要访问提取文件的请求

角度代码:

public sendFiles(files: File[], [...]): Observable<any> {
   const formData = new FormData();
   formData.append('files', files); // add all the other properties
   return this.http.post('http://somehost/someendpoint/fileupload/', formData);
}
公共发送文件(文件:File[],[…]):可观察{ const formData=new formData(); formData.append('files',files);//添加所有其他属性 返回此.http.post('http://somehost/someendpoint/fileupload/,formData); } ASP.NET核心代码:

public class MyFileUploadClass
{
   public IFormFile[] Files { get; set; }
   // other properties
}

[HttpPost("fileupload")]
public async Task<IActionResult> FileUpload([FromForm] MyFileUploadClass @class)  // -> property name must be the same used as formdata key
{
   // do the magic here
   return NoContent();
}
公共类MyFileUploadClass
{
公共文件[]文件{get;set;}
//其他属性
}
[HttpPost(“文件上传”)]
公共异步任务FileUpload([FromForm]MyFileUploadClass@class)/>属性名称必须与formdata键相同
{
//在这里变魔术
返回NoContent();
}

是的,使用多部分/表单数据,您可以从mars以相同的requestHi@agua格式上载文件和数据,谢谢您的帮助,但在您的回答中,您只上载了一个文件。在我的情况下,我想发送多个文件。此外,在使用ChildSampleDetailsTo编写的第二种情况下,如何知道文件属于哪个子级?您可以添加任意数量的文件(
sendable.append('File'+i,files[i],files[i].name)
),您可以在数据中引用您的文件。例如,您可以使用数据的键来引用它:
sendable.append('fileData'+i,JSON.stringify(datas[i])所以在我的例子中,它与SampleDetailsTo一起工作,但是当我想添加ChildSampleDetailsTo时,我没有成功,数组总是空的(但不是nul)。对于文件,此解决方案有效,我可以接收数据服务器端:content_2;.append('images[]',files[I],files[I].name);但不是这一个content.append('images'+i,files[i],files[i].name);你检查内容类型了吗?请求主体呢?您好,谢谢您的帮助,但对我来说不起作用,我在.net core上创建了一个bug,它进一步解释了这个问题:也许您知道修补pb的方法?那么它一定是您的请求。对我来说,它就是这样工作的。在你的github上发布了一个简单的问题。我只是花了大约一个小时的时间试图让它工作,只是发现我的参数名拼写不正确,并且与参数名不匹配。谢谢你!我去过那里!很高兴我能帮忙!
const sendable = new FormData();

for (let i; i < files.length; i++) {
    sendable.append('filedata' + i, files[i], files[i].name);
    sendable.append('data' + i, JSON.stringify(data[i]));
}
const request = new HttpRequest(item.method,
      item.url,
      sendable,
      {
        reportProgress: true
      });
// this._http: HttpClient
this._http.request(request)
      .subscribe((event: any) => {
        if (event.type === HttpEventType.UploadProgress) {
          // on progress code
        }
        if (event.type === HttpEventType.Response) {
          // on response code
        }
      }, error => {
        // on error code
      });
public sendFiles(files: File[], [...]): Observable<any> {
   const formData = new FormData();
   formData.append('files', files); // add all the other properties
   return this.http.post('http://somehost/someendpoint/fileupload/', formData);
}
public class MyFileUploadClass
{
   public IFormFile[] Files { get; set; }
   // other properties
}

[HttpPost("fileupload")]
public async Task<IActionResult> FileUpload([FromForm] MyFileUploadClass @class)  // -> property name must be the same used as formdata key
{
   // do the magic here
   return NoContent();
}