如何从请求中获取正文值(Stream)而不清理它?

时间:2017-07-24 14:07:38

标签: c# asp.net asp.net-web-api

我正在尝试从授权类(AuthorizationHandler)的请求获取正文,但该正文是一个Stream,在阅读了您的内容之后,由于Stream内容已经是一次性的,因此无法执行下一个发布的请求。

我正在使用此代码获取Stream内容:

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, Autorizacao requirement)
{
    var routeValues = context.Resource as AuthorizationFilterContext;
    if (routeValues != null)
    {
        var obj = StreamToObject(routeValues.HttpContext.Request.Body);
        context.Succeed(requirement);
    }
    return Task.FromResult(0);
}

private Object StreamToObject(Stream stream)
{
    try
    {
        string content;
        using (var reader = new StreamReader(stream))
        content = reader.ReadToEnd();
        return Newtonsoft.Json.JsonConvert.DeserializeObject(content);
    }
    catch (Exception e)
    {
        throw e;
    }
}

如何解决此问题?

2 个答案:

答案 0 :(得分:3)

StreamReader有一个特殊的constructor,允许您将布尔值作为最后一个参数传递。它将防止处理潜在的流

编辑:由于ReadToEnd不会在流中恢复位置,您应该自己这样做:

var position = stream.Position;
using (var reader = new StreamReader(stream, Encoding.UTF8, false, 8192, true))
    content = reader.ReadToEnd();
stream.Seek(position, SeekOrigin.Begin);


编辑2:MSDN我看到Body有一个二传手。因此,您可以将原始Body替换为内存流:

if (routeValues != null)
{
    var memoryStream = new MemoryStream();
    routeValues.HttpContext.Request.Body.CopyTo(memoryStream);

    // reset position after CopyTo
    memoryStream.Seek(0, SeekOrigin.Begin);
    var obj = StreamToObject(memoryStream);

    // reset position after ReadToEnd
    memoryStream.Seek(0, SeekOrigin.Begin);
    routeValues.HttpContext.Request.Body = memoryStream;
    context.Succeed(requirement);
}

答案 1 :(得分:0)

也许不再需要了,但是您可以设置NA然后执行request.EnableRewind()

为我工作