我可以在net core中读取Request.Body两次吗?

问题描述 投票:0回答:1

我有一个由第三方调用的 post 方法。为了验证是他们本人,他们对正文进行加密并将其添加为标头。所以我可以做同样的事情并检查是否有效。

我希望将其作为某种属性来执行,这样我就可以在整个控制器中自动重用它,所以我有:

public class Verify : ActionFilter, IAsyncAuthorizationFilter 
{
  public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
  {
    var signature = context.HttpContext.Request.Headers["x-signature"];
    var requestBody = await new StreamReader(context.HttpContext.Request.Body).ReadToEndAsync();
    var key = "my-secure-key";

    if (EncryptTheBody(requestBody, key) != signature) 
    {
      // not valid
      context.Result = new UnauthorizedResult();
    }
    context.HttpContext.Request.Body.Position = 0;  //added this - but doesn't work
  }
}

效果很好。 除了我需要稍后在控制器操作中获取主体

[HttpPost]
[Verify]
public Task Post(MyModel model){  
  // model is all null.  
}

有什么想法吗?解决方案?更好的方法?

我可以将上面的所有内容复制/粘贴到控制器中,删除属性,然后只需使用字符串主体两次,但想避免。

c# asp.net-mvc request
1个回答
0
投票

您可以通过使用请求缓冲来做到这一点,但您必须在第一次读取请求数据之前启用缓冲,包括 ASP.NET 原生读取请求数据。当您进入控制器时,Request.Body 已被读取。 为此,您必须连接一个自定义中间件处理程序,该处理程序必须在添加 ASP.NET 控制器之前运行(在 program.cs/startup.cs 中):

app.Use(async (context, next) => { context.Request.EnableBuffering(); await next(); }

如果您需要在控制器代码之前读取缓冲区,您可以在同一处理程序中使用类似的内容:

app.Use(async (context, next) => { if (context.Request.Method == "POST" || context.Request.Method == "PUT") { string bodyString = null; // this is early enough in the pipeline context.Request.EnableBuffering(); using var reader = new StreamReader(context.Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, leaveOpen: true /* important! */); try { bodyString = await reader.ReadToEndAsync(); // reset the stream to start position if (context.Request.Body.CanSeek) context.Request.Body.Position = 0; } catch(Exception) { bodyString = null; } // ... do something with the capture data } await next(); }

如果您需要在
ASP.NET处理完请求数据之后进行捕获,您可以手动重置流位置,然后进行读取:

[HttpPost] [Verify] public async Task<object> Post(MyModel model){ { Context.HttpContext.Request.Body.Position = 0; // ... READ THE STREAM here as above }

了解更多详细信息
请参阅此博文

© www.soinside.com 2019 - 2024. All rights reserved.