代码之家  ›  专栏  ›  技术社区  ›  Natalie Perret

如何将json数据和formdata(文件)从Angular发送到ASP.NETWebAPI控制器动作一次完成?

  •  1
  • Natalie Perret  · 技术社区  · 6 年前

    假设我有一个ASP.NETWebAPI控制器,如下所示:

    public class StuffController
    {
        [HttpGet]
        [Route("api/v1/stuff/{id:int}")]
        [ResponseType(typeof(Model))]
        public async Task<IHttpActionResult> GetAsync(int id)
        {
            // ...
        }
    
        [HttpPut]
        [Route("api/v1/stuff/{id:int}")]
        [ResponseType(typeof(IHttpActionResult))]
        public async Task<IHttpActionResult> UpdateAsync(int id, Model model)
        {
            // ...
        }
    
        [HttpPost]
        [Route("api/v1/stuff")]
        [ResponseType(typeof(IHttpActionResult))]
        public async Task<IHttpActionResult> CreateAsync([FromBody] Model model)
        {
            // ...
        }
    }
    

    我是否可以从Angular应用程序(显然是在一个正确注入了HttpClient的服务中)发送/上传/发布一个模型(即从主体中提取的json数据)和包含文件的表单数据?

    问题是。。。我真的不明白:

    const formData = new FormData();
    
    const uploadReq = new HttpRequest('POST', url, formData, {
         reportProgress: true,
         headers: headers
    });
    

    就好像是

    • 我必须为每个文件发送不同的“POST”
    1 回复  |  直到 6 年前
        1
  •  3
  •   Dai    6 年前

    发送MIME多部分请求( multipart/form-data ),每个blob都是自己的FormData条目: https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects Request.Content.ReadAsMultipartAsync 应用程序编程接口: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2

    您需要将控制器操作更改为不使用方法参数,而是从 Request 直接:

    public async Task<HttpResponseMessage> PostFormData()
    {
        // Check if the request contains multipart/form-data.
        if( !this.Request.Content.IsMimeMultipartContent() )
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }
    
        // Temporarily write the request to disk (if you use `MultipartMemoryStreamProvider` your risk crashing your server if a malicious user uploads a 2GB+ sized request)
        String root = this.Server.MapPath("~/App_Data");
        MultipartStreamProvider provider = new MultipartFormDataStreamProvider(root);
    
        try
        {
            // Read the form data and serialize it to disk for reading immediately afterwards:
            await this.Request.Content.ReadAsMultipartAsync( provider );
    
            // This illustrates how to get the names each part, but remember these are not necessarily files: they could be form fields, JSON blobs, etc
            foreach( MultipartFileData file in provider.FileData )
            {
                Trace.WriteLine( file.Headers.ContentDisposition.FileName );
                Trace.WriteLine( "Server file path: " + file.LocalFileName );
            }
    
            return this.Request.CreateResponse( HttpStatusCode.OK );
        }
        catch( System.Exception e )
        {
            return this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
        }
    }