如何上传带有附加参数的 IFormFile
How to upload an IFormFile with additional parameters
我有一个现有的 API,它正在从请求正文中读取数据:
[HttpPost]
public async Task<IActionResult> Post([FromBody] CreateVm vm)
{
if (!ModelState.IsValid) return BadRequest();
var result = await _service.CreateAsync(vm);
return Ok(result);
}
一个新的需求进来了,要求客户想要连同视图模型一起提交图像。我的第一个想法是将 IFormFile
附加到请求,在不同的服务中处理它并继续:
public async Task<IActionResult> Post([FromBody] CreateVm vm, IFormFile file) { /* ... */}
这种方法的结果是,我收到状态码 415 "Unsupported Media Type"。
我尝试使用邮递员将 Content-Type 设置为 multipart/form-data
,但无济于事。
这种方法是否可行,或者我是否需要向视图模型添加 byte[]
属性 并从那里解析图像?
我假设,因为这以前在上传您要发送的文件的新要求之前有效 JSON。 (将来,如果您也展示了您是如何提出请求的,将会很有帮助。)
文件可以 "uploaded" 通过 JSON,但它们必须以可以包含在 JSON 对象中的格式发送,即 JS int 数组或 Base64 -编码的字符串。 ASP.NET Core 可以处理任何一个,并将值绑定到 byte[]
.
如果没有发出请求的代码,很难给你比这更多的指导,但你基本上只需要添加一个 byte[]
属性 到你的视图模型,然后当发出请求,读取文件数据并将其作为 int 数组或 Base64 编码的字符串写入 JSON,对应于 属性 名称。例如,如果您通过 JavaScript 发出请求,则可以使用文件 API 获取上传输入中文件的数据。
IFormFile
仅适用于 multipart/form-data
编码请求,使用模型绑定器时不能混合和匹配请求主体编码。因此,您必须停止使用 JSON 或发送 JSON 对象中的文件,如上所述,而不是使用 IFormFile
.
我认为带有 [FromForm]
标签的 form-data 请求应该适合你。
using Microsoft.AspNetCore.Http;
public class CarModelPostDTO {
public string Name { get; set; }
public IFormFile Image { get; set; }
}
[HttpPost("api/car")]
public ActionResult Car([FromForm]CarModelPostDTO carDto)
{
// Getting Name
string name = carDto.Name;
// Getting Image
var image = carDto.Image;
// Saving Image on Server
if (image.Length > 0) {
using (var fileStream = new FileStream(image.FileName, FileMode.Create)) {
image.CopyTo(fileStream);
}
}
return Ok(new { status = true, message = "Car created successfully"});
}
这是一个完整的tutorial。
我有一个现有的 API,它正在从请求正文中读取数据:
[HttpPost]
public async Task<IActionResult> Post([FromBody] CreateVm vm)
{
if (!ModelState.IsValid) return BadRequest();
var result = await _service.CreateAsync(vm);
return Ok(result);
}
一个新的需求进来了,要求客户想要连同视图模型一起提交图像。我的第一个想法是将 IFormFile
附加到请求,在不同的服务中处理它并继续:
public async Task<IActionResult> Post([FromBody] CreateVm vm, IFormFile file) { /* ... */}
这种方法的结果是,我收到状态码 415 "Unsupported Media Type"。
我尝试使用邮递员将 Content-Type 设置为 multipart/form-data
,但无济于事。
这种方法是否可行,或者我是否需要向视图模型添加 byte[]
属性 并从那里解析图像?
我假设,因为这以前在上传您要发送的文件的新要求之前有效 JSON。 (将来,如果您也展示了您是如何提出请求的,将会很有帮助。)
文件可以 "uploaded" 通过 JSON,但它们必须以可以包含在 JSON 对象中的格式发送,即 JS int 数组或 Base64 -编码的字符串。 ASP.NET Core 可以处理任何一个,并将值绑定到 byte[]
.
如果没有发出请求的代码,很难给你比这更多的指导,但你基本上只需要添加一个 byte[]
属性 到你的视图模型,然后当发出请求,读取文件数据并将其作为 int 数组或 Base64 编码的字符串写入 JSON,对应于 属性 名称。例如,如果您通过 JavaScript 发出请求,则可以使用文件 API 获取上传输入中文件的数据。
IFormFile
仅适用于 multipart/form-data
编码请求,使用模型绑定器时不能混合和匹配请求主体编码。因此,您必须停止使用 JSON 或发送 JSON 对象中的文件,如上所述,而不是使用 IFormFile
.
我认为带有 [FromForm]
标签的 form-data 请求应该适合你。
using Microsoft.AspNetCore.Http;
public class CarModelPostDTO {
public string Name { get; set; }
public IFormFile Image { get; set; }
}
[HttpPost("api/car")]
public ActionResult Car([FromForm]CarModelPostDTO carDto)
{
// Getting Name
string name = carDto.Name;
// Getting Image
var image = carDto.Image;
// Saving Image on Server
if (image.Length > 0) {
using (var fileStream = new FileStream(image.FileName, FileMode.Create)) {
image.CopyTo(fileStream);
}
}
return Ok(new { status = true, message = "Car created successfully"});
}
这是一个完整的tutorial。