“HttpRequest”不包含“EnableRewind”的定义

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

我正在尝试在我创建的自定义授权处理程序中使用 EnableRewind 方法,但收到错误“'HttpRequest'不包含'EnableRewind'的定义”,我需要访问其中的正文,但如果我这样做如代码所示,我在控制器中收到错误“输入不包含任何 JSON 令牌。期望输入以有效的 JSON 令牌开头,....”这是我的处理程序,我从启动文件注入了 IHttpContextAccessor

public class ForPrivateProfileBodyMustOwnRecordOrShouldBeInAdminRoleHandler : AuthorizationHandler<ForPrivateProfileBodyMustOwnRecordOrShouldBeInAdminRole>
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public ForPrivateProfileBodyMustOwnRecordOrShouldBeInAdminRoleHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, 
          ForPrivateProfileBodyMustOwnRecordOrShouldBeInAdminRole requirement)
    {
       var reader = new System.IO.StreamReader(_httpContextAccessor.HttpContext.Request.Body);

        
        
        var body = reader.ReadToEndAsync().Result;
        //this line is producing error
        var req = _httpContextAccessor.HttpContext.Request.EnableRewind();
        var request = Newtonsoft.Json.JsonConvert.DeserializeObject<PrivateProfileModel>(body);
        var ownerId = context.User.Claims.FirstOrDefault(c => c.Type == "sub")?.Value;
        if (request.UserId.ToString() != ownerId && !context.User.IsInRole("Admin"))
        {
            context.Fail();
            return Task.CompletedTask;
        }
        //all checks pass
        //_httpContextAccessor.HttpContext.Request.Body.Seek(0, System.IO.SeekOrigin.Begin);
        context.Succeed(requirement);
        return Task.CompletedTask;

    }
}
c# asp.net-core authorization
2个回答
5
投票

最后我解决了这个问题,实际上问题是 ASP .NET Core 使用的特定流 – Microsoft.AspNetCore.Server.Kestrel.Internal.Http.FrameRequestStream – 不可回滚(发现这篇文章非常有帮助http://www .palador.com/2017/05/24/logging-the-body-of-http-request-and-response-in-asp-net-core/)因此通过创建新流并将其放入正文中来解决它这个:

            var body = reader.ReadToEndAsync().Result;
            var request = Newtonsoft.Json.JsonConvert.DeserializeObject<PrivateProfileModel>(body);

            using (var injectedRequestStream = new MemoryStream())
            {
                var bytesToWrite = System.Text.Encoding.UTF8.GetBytes(body);
                injectedRequestStream.Write(bytesToWrite, 0, bytesToWrite.Length);
                injectedRequestStream.Seek(0, SeekOrigin.Begin);
                _httpContextAccessor.HttpContext.Request.Body = injectedRequestStream;
            }

1
投票

EnableRewind()
方法属于
BufferingHelper
,而
BufferingHelper
属于internal类,因此你不能使用它。
但您可以使用
EnableBuffering()
扩展方法来实现此目的。
EnableBuffering()
在内部调用
BufferingHelper.EnableRewind(request)

换句话说,

EnableRewind
EnableBuffering
做同样的事情。

public static class HttpRequestRewindExtensions
{
    ...
  
    public static void EnableBuffering(this HttpRequest request)
    {
        BufferingHelper.EnableRewind(request);
    }

    ...
}

有关更多信息,您可以在此处查看源代码:HttpRequestRewindExtensions

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