Asp.Net Core控制器如何接收原始请求正文内容详解

在Asp.net Core控制器中,通过自定义格式化程序来映射自定义处理控制器中的“未知”内容。本文将给大家详细介绍关于Asp.Net Core控制器接收原始请求正文内容的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

简单案例

为了演示这个问题,我们用VS2017创建一个默认的Asp.net Core Web Api项目。

[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase{ [HttpGet] public ActionResult<string> Get() { return "ok"; } [HttpPost] [Route("PostX")] public ActionResult<string> Post([FromBody] string value) { return value; } }

Json请求

我们从最常见的json输入请求开始。

User-Agent: Fiddler Host: localhost:5000 Content-Type: application/json Content-Length: 16

请求body:

{"123456"}

通过后台调试和fiddler抓包,我们可以看到请求输入和返回。

Asp.Net Core控制器如何接收原始请求正文内容详解

后台调试,查看请求输入结果

Asp.Net Core控制器如何接收原始请求正文内容详解

fiddler查看请求header

Asp.Net Core控制器如何接收原始请求正文内容详解

fiddler查看返回结果

注意!!

别忘了[FromBody],有时候会忘的。
后台action接收类型为string的时候,请求body只能是字符串,不能传json对象。我演示这个例子时,被这点坑了。如果接收对象是一个类的时候,才可以传json对象。

没有JSON

虽然传输json数据是最常用的,但有时候我们需要支持普通的文本或者二进制信息。我们将Content-Type改为
text/plain

User-Agent: Fiddler Host: localhost:5000 Content-Type:text/plain Content-Length: 16

请求body:

{"123456"}

悲剧的事情来,报404!

Asp.Net Core控制器如何接收原始请求正文内容详解


不支持text/plain

事情到此就变得稍微复杂了一些,因为asp.netcore只处理它认识的类型,如json和formdata。默认情况下,原始数据不能直接映射到控制器参数。这是个小坑,不知你踩到过没有?仔细想想,这是有道理的。MVC具有特定内容类型的映射,如果您传递的数据不符合这些内容类型,则无法转换数据,因此它假定没有匹配的端点可以处理请求。
那么怎么支持原始的请求映射呢?

支持原始正文请求

不幸的是,ASP.NET Core不允许您仅通过方法参数以任何有意义的方式捕获“原始”数据。无论如何,您需要对其进行一些自定义处理Request.Body以获取原始数据,然后对其进行反序列化。

您可以捕获原始数据Request.Body并从中直接读取原始缓冲区。

最简单,最不易侵入,但不那么明显的方法是使用一个方法接受没有参数的 POST或PUT数据,然后从Request.Body以下位置读取原始数据:

读取字符串缓冲区

[HttpPost] [Route("PostText")] public async Task<string> PostText() { using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { return await reader.ReadToEndAsync(); } }

这适用于一下Http和文本

User-Agent: Fiddler Host: localhost:5000 Content-Type: text/plain Content-Length: 6

要读取二进制数据,你可以使用以下内容:

读取byte缓冲区

[HttpPost] [Route("PostBinary")] public async Task<byte[]> PostBinary() { using (var ms = new MemoryStream(2048)) { await Request.Body.CopyToAsync(ms); return ms.ToArray(); // returns base64 encoded string JSON result } }

查看执行结果

Asp.Net Core控制器如何接收原始请求正文内容详解

接收文本内容

Asp.Net Core控制器如何接收原始请求正文内容详解

接收二进制数据

HttpRequest静态扩展

如果你为了方便,写了很多HttpRequest的扩展,接收参数时,可以看起来更简洁一些。

public static class HttpRequestExtension { /// <summary> /// /// </summary> /// <param></param> /// <param></param> /// <returns></returns> public static async Task<string> GetRawBodyStringFormater(this HttpRequest httpRequest, Encoding encoding) { if (encoding == null) { encoding = Encoding.UTF8; } using (StreamReader reader = new StreamReader(httpRequest.Body, encoding)) { return await reader.ReadToEndAsync(); } } /// <summary> /// 二进制 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> public static async Task<byte[]> GetRawBodyBinaryFormater(this HttpRequest httpRequest, Encoding encoding) { if (encoding == null) { encoding = Encoding.UTF8; } using (StreamReader reader = new StreamReader(httpRequest.Body, encoding)) { using (var ms = new MemoryStream(2048)) { await httpRequest.Body.CopyToAsync(ms); return ms.ToArray(); // returns base64 encoded string JSON result } } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsffw.html