首页 > 解决方案 > 如何一次性将 Angular 的 json 数据和表单数据(文件)发送到 ASP.NET WebAPI 控制器操作?

问题描述

假设我有一个看起来像这样的 ASP.NET WebAPI 控制器:

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
});

这就像是否...:

标签: c#jsonangularasp.net-web-apimultipartform-data

解决方案


发送一个 MIME 多multipart/form-data部分请求(通过使用Request.Content.ReadAsMultipartAsyncAPI 从 ASP.NET 中的请求: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);
    }
}

推荐阅读