gpt4 book ai didi

asp.net-core - 访问原始请求正文

转载 作者:行者123 更新时间:2023-12-02 10:32:41 24 4
gpt4 key购买 nike

我正在尝试在 ASP.net 5 中访问请求的原始输入正文/流。过去,我能够将输入流的位置重置为 0 并将其读入内存流,但是当我尝试时要从上下文执行此操作,输入流要么为空,要么抛出错误(System.NotSupportedException =>“不支持指定的方法。”)。

在下面的第一个示例中,如果我将 Controller 方法的参数对象类型声明为动态,我可以访问 Controller 中的原始请求。由于各种原因,这不是一个解决方案,无论如何我都需要访问身份验证过滤器中的原始请求正文。

此示例有效,但不是一个合理的解决方案:

[HttpPost("requestme")]
public string GetRequestBody([FromBody] dynamic body)
{
return body.ToString();
}

抛出错误:

[HttpPost("requestme")]
public string GetRequestBody()
{
var m = new MemoryStream();
Request.Body.CopyTo(m);

var contentLength = m.Length;

var b = System.Text.Encoding.UTF8.GetString(m.ToArray());

return b;
}

抛出错误:

[HttpPost("requestme")]
public string GetRequestBody()
{
Request.Body.Position = 0;
var input = new StreamReader(Request.Body).ReadToEnd();

return input;
}

抛出错误:

[HttpPost("requestme")]
public string GetRequestBody()
{
Request.Body.Position = 0;
var input = new MemoryStream();
Request.Body.CopyTo(input);

var inputString = System.Text.Encoding.UTF8.GetString(input.ToArray());

return inputString;
}

我需要访问我正在构建的 API 传入的每个请求的原始请求正文。

任何帮助或指导将不胜感激!

编辑:

这是我想要读取请求正文的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Http;

namespace API.Filters
{
public class CustomAuthorizationAttribute : Attribute, IAuthorizationFilter
{
public CustomAuthorizationAttribute()
{ }

public void OnAuthorization(AuthorizationContext context)
{
if (context == null)
throw new ArgumentNullException("OnAuthorization AuthorizationContext context can not be null.");
else
{
if (this.AuthorizeCore(context.HttpContext) == false)
{
// Do Other Stuff To Check Auth
}
else
{
context.Result = new HttpUnauthorizedResult();
}
}
}

protected virtual bool AuthorizeCore(HttpContext httpContext)
{
var result = false;

using (System.IO.MemoryStream m = new System.IO.MemoryStream())
{
try
{
if (httpContext.Request.Body.CanSeek == true)
httpContext.Request.Body.Position = 0;

httpContext.Request.Body.CopyTo(m);

var bodyString = System.Text.Encoding.UTF8.GetString(m.ToArray());

return CheckBody(bodyString); // Initial Auth Check returns true/false <-- Not Shown In Code Here on Stack Overflow
}
catch (Exception ex)
{
Logger.WriteLine(ex.Message);
}
}
return false;
}
}
}

当调用像这样标记有 CustomAuthorization 属性的 Controller 方法时,将访问此代码。

[Filters.CustomAuthorizationAuthorization]
[HttpPost]
public ActionResult Post([FromBody]UserModel Profile)
{
// Process Profile
}

最佳答案

更新
下面的信息现在已经相当过时了。由于性能原因,默认情况下这是不可能的,但幸运的是可以更改。最新的解决方案应该是使用 EnableBuffering 启用请求缓冲:

Request.EnableBuffering();

另请参阅此博文了解更多信息:https://devblogs.microsoft.com/aspnet/re-reading-asp-net-core-request-bodies-with-enablebuffering/ .

<小时/>

旧的、过时的引用答案

Request.Body 的实现取决于 Controller 操作。

如果操作包含参数,则由 Microsoft.AspNet.WebUtilities.FileBufferingReadStream 实现,它支持查找 (Request.Body.CanSeek == true)。此类型还支持设置 Request.Body.Position

但是,如果您的操作不包含任何参数,则它是由 Microsoft.AspNet.Loader.IIS.FeatureModel.RequestBody 实现的,它支持查找(Request .Body.CanSeek == false)。这意味着您无法调整 Position 属性,您可以直接开始读取流。

这种差异可能与 MVC 需要从请求正文中提取参数值有关,因此它需要读取请求。

就您而言,您的操作没有任何参数。因此使用 Microsoft.AspNet.Loader.IIS.FeatureModel.RequestBody,如果您尝试设置 Position 属性,它会引发异常。

<小时/>**解决方案**:要么不设置位置,要么先检查您是否确实_可以_设置位置:
if (Request.Body.CanSeek)
{
// Reset the position to zero to read from the beginning.
Request.Body.Position = 0;
}

var input = new StreamReader(Request.Body).ReadToEnd();

关于asp.net-core - 访问原始请求正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31678990/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com