如何一次性将 json 数据和表单数据(文件)从 Angular 发送到 ASP.NET WebAPI 控制器操作?
How to send json data and formdata (files) from Angular to an ASP.NET WebAPI Controller action in one shot?
假设我有一个看起来像这样的 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 的服务中)发送/上传/post 模型(这是 json 数据将从正文中提取)和包含文件的表单数据...)?
问题是...我真的不明白:
const formData = new FormData();
const uploadReq = new HttpRequest('POST', url, formData, {
reportProgress: true,
headers: headers
});
好像...:[=15=]
- 我将 json 数据添加为表单数据的一部分,并且无法在 Web API 控制器操作中将其作为 "such" 从正文中提取,我必须保留Angular 应用程序中用于 json 数据的密钥,然后遍历剩余的密钥(据说是所有文件)。
- 我必须为每个文件发送不同的"POST"
发送一个 MIME 多部分请求(multipart/form-data
),每个 blob 都是它自己的 FormData 条目:https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects - on the server-side you can extract different parts from the request in ASP.NET by using the Request.Content.ReadAsMultipartAsync
API: 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);
}
}
假设我有一个看起来像这样的 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 的服务中)发送/上传/post 模型(这是 json 数据将从正文中提取)和包含文件的表单数据...)?
问题是...我真的不明白:
const formData = new FormData();
const uploadReq = new HttpRequest('POST', url, formData, {
reportProgress: true,
headers: headers
});
好像...:[=15=]
- 我将 json 数据添加为表单数据的一部分,并且无法在 Web API 控制器操作中将其作为 "such" 从正文中提取,我必须保留Angular 应用程序中用于 json 数据的密钥,然后遍历剩余的密钥(据说是所有文件)。
- 我必须为每个文件发送不同的"POST"
发送一个 MIME 多部分请求(multipart/form-data
),每个 blob 都是它自己的 FormData 条目:https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects - on the server-side you can extract different parts from the request in ASP.NET by using the Request.Content.ReadAsMultipartAsync
API: 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);
}
}