Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何阅读HttpResponse正文?_C#_Asp.net Core_.net Core - Fatal编程技术网

C# 如何阅读HttpResponse正文?

C# 如何阅读HttpResponse正文?,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,我有一个带有请求和响应日志记录中间件的.NET核心Web API项目。我在Startup文件的Configure方法中注册了这两个中间件文件 app.UseMiddleware<RequestLoggingMiddleware>(); app.UseMiddleware<ResponseLoggingMiddleware>(); 但不幸的是我得到了这个例外 System.ArgumentException:流不可读 有人知道如何修复它吗?您可以使用StreamReade

我有一个带有请求和响应日志记录中间件的.NET核心Web API项目。我在
Startup
文件的
Configure
方法中注册了这两个中间件文件

app.UseMiddleware<RequestLoggingMiddleware>();
app.UseMiddleware<ResponseLoggingMiddleware>();
但不幸的是我得到了这个例外

System.ArgumentException:流不可读


有人知道如何修复它吗?

您可以使用StreamReader读取请求正文。下面的代码,您可以按照

            string body = string.Empty;
            Request.EnableRewind();
            using (var reader = new StreamReader(Request.Body))
            {
                Request.Body.Seek(0, SeekOrigin.Begin);
                body = reader.ReadToEnd();
            }
同样的方法,你可以得到一个响应体

            using (var reader = new StreamReader(Response.Body))
            {
                Response.Body.Seek(0, SeekOrigin.Begin);
                body = reader.ReadToEnd();
            }

根据这里接受的答案

我对解决方案做了一点修改,使它起了作用。我想分享我的解决方案,如何记录每个传入的请求和每个传出的响应

如果您认为此解决方案容易出错或可以改进,请发表评论

对于请求日志记录:

public class RequestLoggingMiddleware
{
    private readonly RequestDelegate requestDelegate;
    private readonly ILogger<RequestLoggingMiddleware> logger;

    public RequestLoggingMiddleware(RequestDelegate requestDelegate, ILogger<RequestLoggingMiddleware> logger)
    {
        this.requestDelegate = requestDelegate;
        this.logger = logger;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        await LogRequest(httpContext.Request);
        await requestDelegate(httpContext);
    }

    private async Task LogRequest(HttpRequest httpRequest)
    {
        StringBuilder stringBuilder = new StringBuilder();

        AppendMethod(httpRequest, stringBuilder);
        AppendPath(httpRequest, stringBuilder);
        AppendContentType(httpRequest, stringBuilder);
        AppendHeaders(httpRequest, stringBuilder);
        AppendParams(httpRequest, stringBuilder);
        AppendQueries(httpRequest, stringBuilder);
        await AppendBody(httpRequest, stringBuilder);

        logger.LogTrace(stringBuilder.ToString());
    }

    private void AppendMethod(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        stringBuilder.AppendLine($"Method: {httpRequest.Method}");
    }

    private void AppendPath(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        stringBuilder.AppendLine($"Path: {httpRequest.Path.Value}");
    }

    private void AppendContentType(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        string contentType = httpRequest.ContentType;

        if (!string.IsNullOrEmpty(contentType))
        {
            stringBuilder.AppendLine($"Content type: {contentType}");
        }
    }

    private void AppendHeaders(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        AppendCollection(httpRequest.Headers, "Headers", stringBuilder);
    }

    private void AppendParams(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        AppendCollection(httpRequest.RouteValues, "Params", stringBuilder);
    }

    private void AppendQueries(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        AppendCollection(httpRequest.Query, "Queries", stringBuilder);
    }

    private void AppendCollection<TKey, TValue>(
        IEnumerable<KeyValuePair<TKey, TValue>> collection,
        string collectionName,
        StringBuilder stringBuilder)
    {
        if (collection.Any())
        {
            stringBuilder.AppendLine($"{collectionName}:");

            foreach ((TKey key, TValue value) in collection)
            {
                stringBuilder.AppendLine($"\t{key}: {value}");
            }
        }
    }

    private async Task AppendBody(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        httpRequest.EnableBuffering();

        ReadResult bodyReadResult = await httpRequest.BodyReader.ReadAsync();
        ReadOnlySequence<byte> bodyBuffer = bodyReadResult.Buffer;

        if (bodyBuffer.Length > 0)
        {
            byte[] bodyBytes = bodyBuffer.ToArray();
            string bodyText = Encoding.UTF8.GetString(bodyBytes);
            stringBuilder.AppendLine($"Body: {bodyText}");
        }

        httpRequest.Body.Seek(0, SeekOrigin.Begin);
    }
}
公共类requestLogging中间件
{
私有只读RequestDelegate RequestDelegate;
专用只读ILogger记录器;
公共RequestLoggingMiddleware(RequestDelegate、RequestDelegate、ILogger记录器)
{
this.requestDelegate=requestDelegate;
this.logger=记录器;
}
公共异步任务InvokeAsync(HttpContext HttpContext)
{
等待LogRequest(httpContext.Request);
等待请求委托(httpContext);
}
专用异步任务日志请求(HttpRequest HttpRequest)
{
StringBuilder StringBuilder=新的StringBuilder();
AppendMethod(httpRequest、stringBuilder);
AppendPath(httpRequest、stringBuilder);
AppendContentType(httpRequest、stringBuilder);
附录标题(httpRequest、stringBuilder);
AppendParams(httpRequest、stringBuilder);
附加查询(httpRequest、stringBuilder);
等待AppendBody(httpRequest、stringBuilder);
logger.LogTrace(stringBuilder.ToString());
}
私有方法(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
AppendLine($“方法:{httpRequest.Method}”);
}
私有无效附加路径(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
stringBuilder.AppendLine($“路径:{httpRequest.Path.Value}”);
}
私有void AppendContentType(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
字符串contentType=httpRequest.contentType;
如果(!string.IsNullOrEmpty(contentType))
{
AppendLine($“内容类型:{contentType}”);
}
}
私有void AppendHeaders(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
AppendCollection(httpRequest.Headers,“Headers”,stringBuilder);
}
私有void AppendParams(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
AppendCollection(httpRequest.RouteValue,“参数”,stringBuilder);
}
私有查询(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
AppendCollection(httpRequest.Query,“查询”,stringBuilder);
}
私人收藏(
IEnumerable collection,
字符串集合名称,
StringBuilder(StringBuilder)
{
if(collection.Any())
{
AppendLine($“{collectionName}:”);
集合中的foreach((TKey键,TValue值)
{
AppendLine($“\t{key}:{value}”);
}
}
}
专用异步任务AppendBody(HttpRequest HttpRequest、StringBuilder StringBuilder)
{
httpRequest.EnableBuffering();
ReadResult bodyReadResult=等待httpRequest.BodyReader.ReadAsync();
ReadOnlySequence bodyBuffer=bodyReadResult.Buffer;
如果(bodyBuffer.Length>0)
{
byte[]bodyBytes=bodyBuffer.ToArray();
字符串bodyText=Encoding.UTF8.GetString(bodyBytes);
AppendLine($“Body:{bodyText}”);
}
httpRequest.Body.Seek(0,SeekOrigin.Begin);
}
}
响应日志记录有点不同

public class ResponseLoggingMiddleware
{
    private readonly RequestDelegate requestDelegate;
    private readonly ILogger<RequestLoggingMiddleware> logger;

    public ResponseLoggingMiddleware(RequestDelegate requestDelegate, ILogger<RequestLoggingMiddleware> logger)
    {
        this.requestDelegate = requestDelegate;
        this.logger = logger;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        HttpResponse httpResponse = httpContext.Response;
        Stream originalBody = httpResponse.Body;

        try
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                httpResponse.Body = memoryStream;

                await requestDelegate(httpContext);
                await LogResponse(httpContext.Response, originalBody, memoryStream);
            }
        }
        finally
        {
            httpContext.Response.Body = originalBody;
        }
    }

    private async Task LogResponse(HttpResponse httpResponse, Stream originalBody, MemoryStream memoryStream)
    {
        StringBuilder stringBuilder = new StringBuilder();

        AppendStatusCode(httpResponse, stringBuilder);
        AppendContentType(httpResponse, stringBuilder);
        await AppendBody(httpResponse, stringBuilder, originalBody, memoryStream);

        logger.LogTrace(stringBuilder.ToString());
    }

    private void AppendStatusCode(HttpResponse httpResponse, StringBuilder stringBuilder)
    {
        stringBuilder.AppendLine($"Status code: {httpResponse.StatusCode}");
    }

    private void AppendContentType(HttpResponse httpResponse, StringBuilder stringBuilder)
    {
        string contentType = httpResponse.ContentType;

        if (!string.IsNullOrEmpty(contentType))
        {
            stringBuilder.AppendLine($"Content type: {contentType}");
        }
    }

    private async Task AppendBody(HttpResponse httpResponse, StringBuilder stringBuilder, Stream originalBody, MemoryStream memoryStream)
    {
        httpResponse.Body.Seek(0, SeekOrigin.Begin);

        StreamReader streamReader = new StreamReader(memoryStream);
        string bodyText = await streamReader.ReadToEndAsync();

        if (bodyText.Length > 0)
            stringBuilder.AppendLine($"Body: {bodyText}");

        httpResponse.Body.Seek(0, SeekOrigin.Begin);
        await memoryStream.CopyToAsync(originalBody);
    }
}
公共类响应日志中间件
{
私有只读RequestDelegate RequestDelegate;
专用只读ILogger记录器;
公共响应日志中间件(RequestDelegate RequestDelegate、ILogger logger)
{
this.requestDelegate=requestDelegate;
this.logger=记录器;
}
公共异步任务InvokeAsync(HttpContext HttpContext)
{
HttpResponse HttpResponse=httpContext.Response;
Stream originalBody=httpResponse.Body;
尝试
{
使用(MemoryStream MemoryStream=new MemoryStream())
{
httpResponse.Body=内存流;
等待请求委托(httpContext);
等待LogResponse(httpContext.Response、originalBody、memoryStream);
}
}
最后
{
httpContext.Response.Body=原始正文;
}
}
专用异步任务日志响应(HttpResponse HttpResponse、流原始体、MemoryStream MemoryStream)
{
StringBuilder StringBuilder=新的StringBuilder();
AppendStatusCode(httpResponse、stringBuilder);
AppendContentType(httpResponse、stringBuilder);
等待AppendBody(httpResponse、stringBuilder、originalBody、memoryStream);
logger.LogTrace(stringBuilder.ToString());
}
私有状态代码(HttpResponse HttpResponse,StringBuilder StringBuilder)
{
stringBuilder.AppendLine($“状态代码:{httpResponse.StatusCode}”);
}
私有void AppendContentType(HttpResponse HttpResponse,StringBuilder StringBuilder)
{
字符串contentType=httpResponse.contentType;
如果(!string.IsNullOrEmpty(contentType))
{
AppendLine($“内容类型:{contentType}”);
}
}
专用异步任务AppendBody(HttpResponse HttpResponse、StringBuilder StringBuilder、Stream originalBody、MemoryStream MemoryStream)
{
httpResponse
public class RequestLoggingMiddleware
{
    private readonly RequestDelegate requestDelegate;
    private readonly ILogger<RequestLoggingMiddleware> logger;

    public RequestLoggingMiddleware(RequestDelegate requestDelegate, ILogger<RequestLoggingMiddleware> logger)
    {
        this.requestDelegate = requestDelegate;
        this.logger = logger;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        await LogRequest(httpContext.Request);
        await requestDelegate(httpContext);
    }

    private async Task LogRequest(HttpRequest httpRequest)
    {
        StringBuilder stringBuilder = new StringBuilder();

        AppendMethod(httpRequest, stringBuilder);
        AppendPath(httpRequest, stringBuilder);
        AppendContentType(httpRequest, stringBuilder);
        AppendHeaders(httpRequest, stringBuilder);
        AppendParams(httpRequest, stringBuilder);
        AppendQueries(httpRequest, stringBuilder);
        await AppendBody(httpRequest, stringBuilder);

        logger.LogTrace(stringBuilder.ToString());
    }

    private void AppendMethod(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        stringBuilder.AppendLine($"Method: {httpRequest.Method}");
    }

    private void AppendPath(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        stringBuilder.AppendLine($"Path: {httpRequest.Path.Value}");
    }

    private void AppendContentType(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        string contentType = httpRequest.ContentType;

        if (!string.IsNullOrEmpty(contentType))
        {
            stringBuilder.AppendLine($"Content type: {contentType}");
        }
    }

    private void AppendHeaders(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        AppendCollection(httpRequest.Headers, "Headers", stringBuilder);
    }

    private void AppendParams(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        AppendCollection(httpRequest.RouteValues, "Params", stringBuilder);
    }

    private void AppendQueries(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        AppendCollection(httpRequest.Query, "Queries", stringBuilder);
    }

    private void AppendCollection<TKey, TValue>(
        IEnumerable<KeyValuePair<TKey, TValue>> collection,
        string collectionName,
        StringBuilder stringBuilder)
    {
        if (collection.Any())
        {
            stringBuilder.AppendLine($"{collectionName}:");

            foreach ((TKey key, TValue value) in collection)
            {
                stringBuilder.AppendLine($"\t{key}: {value}");
            }
        }
    }

    private async Task AppendBody(HttpRequest httpRequest, StringBuilder stringBuilder)
    {
        httpRequest.EnableBuffering();

        ReadResult bodyReadResult = await httpRequest.BodyReader.ReadAsync();
        ReadOnlySequence<byte> bodyBuffer = bodyReadResult.Buffer;

        if (bodyBuffer.Length > 0)
        {
            byte[] bodyBytes = bodyBuffer.ToArray();
            string bodyText = Encoding.UTF8.GetString(bodyBytes);
            stringBuilder.AppendLine($"Body: {bodyText}");
        }

        httpRequest.Body.Seek(0, SeekOrigin.Begin);
    }
}
public class ResponseLoggingMiddleware
{
    private readonly RequestDelegate requestDelegate;
    private readonly ILogger<RequestLoggingMiddleware> logger;

    public ResponseLoggingMiddleware(RequestDelegate requestDelegate, ILogger<RequestLoggingMiddleware> logger)
    {
        this.requestDelegate = requestDelegate;
        this.logger = logger;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        HttpResponse httpResponse = httpContext.Response;
        Stream originalBody = httpResponse.Body;

        try
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                httpResponse.Body = memoryStream;

                await requestDelegate(httpContext);
                await LogResponse(httpContext.Response, originalBody, memoryStream);
            }
        }
        finally
        {
            httpContext.Response.Body = originalBody;
        }
    }

    private async Task LogResponse(HttpResponse httpResponse, Stream originalBody, MemoryStream memoryStream)
    {
        StringBuilder stringBuilder = new StringBuilder();

        AppendStatusCode(httpResponse, stringBuilder);
        AppendContentType(httpResponse, stringBuilder);
        await AppendBody(httpResponse, stringBuilder, originalBody, memoryStream);

        logger.LogTrace(stringBuilder.ToString());
    }

    private void AppendStatusCode(HttpResponse httpResponse, StringBuilder stringBuilder)
    {
        stringBuilder.AppendLine($"Status code: {httpResponse.StatusCode}");
    }

    private void AppendContentType(HttpResponse httpResponse, StringBuilder stringBuilder)
    {
        string contentType = httpResponse.ContentType;

        if (!string.IsNullOrEmpty(contentType))
        {
            stringBuilder.AppendLine($"Content type: {contentType}");
        }
    }

    private async Task AppendBody(HttpResponse httpResponse, StringBuilder stringBuilder, Stream originalBody, MemoryStream memoryStream)
    {
        httpResponse.Body.Seek(0, SeekOrigin.Begin);

        StreamReader streamReader = new StreamReader(memoryStream);
        string bodyText = await streamReader.ReadToEndAsync();

        if (bodyText.Length > 0)
            stringBuilder.AppendLine($"Body: {bodyText}");

        httpResponse.Body.Seek(0, SeekOrigin.Begin);
        await memoryStream.CopyToAsync(originalBody);
    }
}