[英]ASP.NET Core Web API - Get file along with [FromBody] JSON model
I have an existing API endpoint that receives data from a the client.我有一个现有的 API 端点,它从客户端接收数据。 I want to add the ability to receive files on that endpoint along with the data.
我想添加在该端点上接收文件以及数据的功能。 This is my model:
这是我的 model:
public class TestModel
{
public IList<IFormFile> File { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Hobbies { get; set; }
}
And this is my endpoint:这是我的终点:
[HttpPost]
[Route("upload")]
public async Task<ActionResult> UploadTest([FromBody] TestModel test)
{
return Ok();
}
I'm currently testing my API with Postman.我目前正在用 Postman 测试我的 API。 I know that in Postman there is an option to send files with
form-data
as the body, but in such case my client would need to use form-data
and I with to use json as data (using FromBody
).我知道在 Postman 中有一个选项可以发送带有
form-data
文件,但在这种情况下,我的客户需要使用form-data
,而我使用 json 作为数据(使用FromBody
)。
I can't find a way how to do that - is it possible?我找不到如何做到这一点的方法 - 有可能吗? And if so, how do I use Postman to send the file view
raw
json?如果是这样,我如何使用 Postman 发送文件视图
raw
json?
When uploading files, if you choose to use JSON, then you are putting the client in a pickle.上传文件时,如果您选择使用 JSON,那么您将客户端置于泡菜中。 You are going to force the client to have to Base64-encode all files.
您将强制客户端必须对所有文件进行 Base64 编码。 This can be a cumbersome task for clients to do especially if it's browser JS code.
对于客户端来说,这可能是一项繁琐的任务,特别是如果它是浏览器 JS 代码。 Not to mention you increase your payload 33%.
更不用说你增加了 33% 的有效载荷。
When posting files, you want to use HTML forms.发布文件时,您要使用 HTML forms。 This is something a browser is very good at.
这是浏览器非常擅长的事情。
With that being said, the proper way to do this would be to set up your endpoint to look like this:话虽如此,正确的方法是将端点设置为如下所示:
// NOTE: This is the same as you have it in your question
public class TestModel
{
public IList<IFormFile> File { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Hobbies { get; set; }
}
[HttpPost, Route("testme")]
public IActionResult TestMe([FromForm] TestModel testModel)
{
return Ok();
}
Take note of the [FromForm]
parameter.记下
[FromForm]
参数。
Then set up postman to look like this:然后设置 postman 看起来像这样:
Post
.Post
。Body
section and set it to Form-Data
. Body
部分并将其设置为Form-Data
。Send
.Send
。 When the endpoint gets hit, it should look like this:当端点被命中时,它应该如下所示:
Let's say you absolutely must use JSON as the post data.假设您绝对必须使用 JSON 作为发布数据。 Then your model will look like this:
然后您的 model 将如下所示:
public class TestModel
{
public IList<byte[]> File { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Hobbies { get; set; }
}
You would change your endpoint from [FromForm]
to [FromBody]
, then you will have to convince your front-end devs they must encode all files with Base64
and build a JSON object to send.您将端点从
[FromForm]
更改为[FromBody]
,然后您必须说服前端开发人员他们必须使用Base64
对所有文件进行编码并构建 JSON ZA8CFDE6331BD59EB2AC96F8911C4B66 到 send。 I don't think you will be super successful with that as it's not optimized nor is it the norm.我认为您不会因此而获得超级成功,因为它没有经过优化,也不是常态。 They may give you strange looks.
他们可能会给你奇怪的表情。
Let's run through the scenario:让我们来看看这个场景:
You will run in to OutOfMemory exceptions at some point.您将在某个时候遇到 OutOfMemory 异常。 It's almost guaranteed.
几乎可以保证。
Form data is extremely optimized in ASP.NET Core.表格数据在 ASP.NET 内核中得到了极大的优化。 It will use memory for smaller files, but then dump to disk for larger files.
它将使用 memory 处理较小的文件,然后转储到磁盘以获取较大的文件。 It's impossible to run in to memory issues when using Form data.
使用表单数据时不可能遇到 memory 问题。
Let's run though a Form scenario:让我们运行一个表单场景:
IFormFile
data exceed 5 MB (I believe that's the limit), it will move it from an in-memory stream to a disk stream.IFormFile
数据超过 5 MB(我相信这是限制),它会将其从内存 stream 移动到磁盘 stream。 PostMan? PostMan? There isn't a way to do this in PostMan without scripting something, again because it's not normal to do.
在 PostMan 中没有任何方法可以在不编写脚本的情况下执行此操作,同样因为这不正常。 I'm sure if you google the subject you may find something, but it will be kludgy at best.
我敢肯定,如果你用谷歌搜索这个主题,你可能会找到一些东西,但充其量只是很笨拙。
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Test.Controllers
{
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
[HttpPost]
[Route("upload")]
public async Task<ActionResult> UploadTest([FromForm] TestModel test)
{
return Ok();
}
}
public class TestModel
{
public IList<IFormFile> File { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Hobbies { get; set; }
}
}
Here is what the request should look like from postman.这是来自 postman 的请求的样子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.