![](/img/trans.png)
[英]calling asp.net mvc 5 web api in asp.net core, FromBody always null
[英]ASP.NET Core Web API - Get file along with [FromBody] JSON model
我有一个现有的 API 端点,它从客户端接收数据。 我想添加在该端点上接收文件以及数据的功能。 这是我的 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; }
}
这是我的终点:
[HttpPost]
[Route("upload")]
public async Task<ActionResult> UploadTest([FromBody] TestModel test)
{
return Ok();
}
我目前正在用 Postman 测试我的 API。 我知道在 Postman 中有一个选项可以发送带有form-data
文件,但在这种情况下,我的客户需要使用form-data
,而我使用 json 作为数据(使用FromBody
)。
我找不到如何做到这一点的方法 - 有可能吗? 如果是这样,我如何使用 Postman 发送文件视图raw
json?
上传文件时,如果您选择使用 JSON,那么您将客户端置于泡菜中。 您将强制客户端必须对所有文件进行 Base64 编码。 对于客户端来说,这可能是一项繁琐的任务,特别是如果它是浏览器 JS 代码。 更不用说你增加了 33% 的有效载荷。
发布文件时,您要使用 HTML forms。 这是浏览器非常擅长的事情。
话虽如此,正确的方法是将端点设置为如下所示:
// 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();
}
记下[FromForm]
参数。
然后设置 postman 看起来像这样:
Post
。Body
部分并将其设置为Form-Data
。Send
。当端点被命中时,它应该如下所示:
假设您绝对必须使用 JSON 作为发布数据。 然后您的 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; }
}
您将端点从[FromForm]
更改为[FromBody]
,然后您必须说服前端开发人员他们必须使用Base64
对所有文件进行编码并构建 JSON ZA8CFDE6331BD59EB2AC96F8911C4B66 到 send。 我认为您不会因此而获得超级成功,因为它没有经过优化,也不是常态。 他们可能会给你奇怪的表情。
让我们来看看这个场景:
您将在某个时候遇到 OutOfMemory 异常。 几乎可以保证。
表格数据在 ASP.NET 内核中得到了极大的优化。 它将使用 memory 处理较小的文件,然后转储到磁盘以获取较大的文件。 使用表单数据时不可能遇到 memory 问题。
让我们运行一个表单场景:
IFormFile
数据超过 5 MB(我相信这是限制),它会将其从内存 stream 移动到磁盘 stream。PostMan? 在 PostMan 中没有任何方法可以在不编写脚本的情况下执行此操作,同样因为这不正常。 我敢肯定,如果你用谷歌搜索这个主题,你可能会找到一些东西,但充其量只是很笨拙。
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; }
}
}
这是来自 postman 的请求的样子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.