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

[HttpPost] [Route("PostTextX")] public async Task<string> PostTextX() { return await Request.GetRawBodyStringAsyn(); } /// <summary> /// 接收 /// </summary> /// <returns></returns> [HttpPost] [Route("PostBinaryX")] public async Task<byte[]> PostBinaryX() { return await Request.GetRawBodyBinaryAsyn(); }

自动转换文本和二进制值

上面虽然解决了原始参数转换问题,但不够友好。如果你打算像原生MVC那样自动映射参数的话,你需要做一些自定义格式化适配。

创建一个Asp.net MVC InputFormatter

ASP.NET Core使用一种干净且更通用的方式来处理内容的自定义格式InputFormatter。输入格式化程序挂钩到请求处理管道,让您查看特定类型的内容以确定是否要处理它。然后,您可以阅读请求正文并对入站内容执行自己的反序列化。

InputFormatter有几个要求

您需要使用[FromBody]去获取

您必须能够查看请求并确定是否以及如何处理内容。

在这个例子中,对于“原始内容”,我想查看具有以下类型的请求:

text/plain(文本)

appliaction/octet-stream(byte[])
没有内容类型(string)

要创建格式化程序,你可以实现IInputFormatter或者从InputFormatter继承。

public class RawRequestBodyFormatter : IInputFormatter { public RawRequestBodyFormatter() { } public bool CanRead(InputFormatterContext context) { if (context == null) throw new ArgumentNullException("argument is Null"); var contentType = context.HttpContext.Request.ContentType; if (string.IsNullOrEmpty(contentType) || contentType == "text/plain" || contentType == "application/octet-stream") return true; return false; } public async Task<InputFormatterResult> ReadAsync(InputFormatterContext context) { var request = context.HttpContext.Request; var contentType = context.HttpContext.Request.ContentType; if (string.IsNullOrEmpty(contentType) || contentType.ToLower() == "text/plain") { using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8)) { var content = await reader.ReadToEndAsync(); return await InputFormatterResult.SuccessAsync(content); } } if (contentType == "application/octet-stream") { using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8)) { using (var ms = new MemoryStream(2048)) { await request.Body.CopyToAsync(ms); var content = ms.ToArray(); return await InputFormatterResult.SuccessAsync(content); } } } return await InputFormatterResult.FailureAsync(); } }

格式化程序用于CanRead()检查对内容类型的请求以支持,然后将ReadRequestBodyAsync()内容读取和反序列化为应在控制器方法的参数中返回的结果类型。

InputFormatter必须在ConfigureServices()启动代码中注册MVC :

public void ConfigureServices(IServiceCollection services) { services.AddMvc(o=>o.InputFormatters.Insert(0,new RawRequestBodyFormatter())).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }

接受原始输入

[HttpPost] [Route("PostTextPlus")] public string PostTextPlus([FromBody] string value) { return value; }

然后你就可以发送post请求,像这样:

User-Agent: Fiddler Host: localhost:5000 Content-Length: 6

或者

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

请注意,您可以使用内容类型调用相同的控制器方法application/json并传递JSON字符串,这也将起作用。在RawRequestBodyFormatter 简单地增加它支持的附加内容类型的支持。

二进制数据

[HttpPost] [Route("PostBinaryPlus")] public byte[] PostBinaryPlus([FromBody] byte[] value) { return value; }

请求内容如下:

User-Agent: Fiddler Host: localhost:5000 Content-Length: 6 Content-Type: application/octet-stream

源代码

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

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