首页 > 解决方案 > 对于 asp.net core web api,使用自定义中间件类会导致 web api 不渲染 JSON 正文

问题描述

我有一个非常基本的 asp.net core web api。我想添加日志记录。我做了一个网络搜索,发现了一个很好的例子,文章的作者在这个例子中演示了如何使用中间件来实现一个记录器。

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {


        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c => {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
                c.OAuthClientId("m2m");
                c.OAuthClientSecret("secret");
            });
        }

        app.UseMiddleware<ApiLogger>();

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

这是记录器:

public class ApiLogger
{
    private readonly RequestDelegate _next;
    private ApiLoggerDatabaseService _dbLogger;

    public ApiLogger(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext, ApiLoggerDatabaseService dbLogger)
    {
        try
        {
            _dbLogger = dbLogger;

            var request = httpContext.Request;
            if (request.Path.StartsWithSegments(new PathString("/api")))
            {
                var stopWatch = Stopwatch.StartNew();
                var requestTime = DateTime.UtcNow;
                //var requestBodyContent = await ReadRequestBody(request);
                long requestLength = request.ContentLength.HasValue ? request.ContentLength.Value : 0;
                var originalBodyStream = httpContext.Response.Body;
                using (var responseBody = new MemoryStream())
                {
                    var response = httpContext.Response;
                    response.Body = responseBody;
                    await _next(httpContext);
                    stopWatch.Stop();

                    //string responseBodyContent = null;
                    //responseBodyContent = await ReadResponseBody(response);
                    //await responseBody.CopyToAsync(originalBodyStream);
                    var responseCode = response.StatusCode;

                    await SafeLog(
                        requestTime,
                        stopWatch.ElapsedMilliseconds,
                        response.StatusCode,
                        request.Method,
                        request.Path,
                        request.QueryString.ToString(),
                        requestLength, 
                        request.HttpContext.Connection.RemoteIpAddress.ToString()
                        );
                }
            }
            else
            {
                await _next(httpContext);
            }
        }
        catch (Exception ex)
        {
            await _next(httpContext);
        }
    }

    private async Task SafeLog(DateTime requestTime,
                long responseMillis,
                int statusCode,
                string method,
                string path,
                string queryString,
                long requestLength, 
                string ipAddress)
    {
       
        var browserName = "Not applicable for API";
        var browserVersion = "Not applicable for API";
        var browserOS = "Not applicable for API";
        var aspSessionId = "Not applicable for API";
        var host = "asp.net core web api";
        var userKey = 4; //TODO
        var customerId = 1; //TODO
        var facilityID = 1; //TODO
        var referrer = "Not applicable for API";
        var responseRedirectLocation = "Not applicable for API";
        var requestFormVars = "";
        var webRequestID = 0;

        await _dbLogger.Log(new APILog
        {
            BrowserName = browserName, 
            BrowserVersion = browserVersion, 
            BrowserOS = browserOS, 
            IPAddress = ipAddress, 
            ASPSessionID = aspSessionId, 
            Host = host, 
            RequestStart = requestTime, 
            RequestLength = requestLength,
            UserKey = userKey, 
            CustomerID = customerId, 
            ResponseStatusCode = statusCode, 
            FacilityID = facilityID, 
            PageName = path,
            QueryString = queryString, 
            Referrer = referrer,
            ResponseRedirectLocation = responseRedirectLocation, 
            RequestFormVars = requestFormVars, 
            WebRequestID = webRequestID
        });
    }
}

但是,我注意到由于添加了记录器,web api 不再在响应中提供 JSON 正文!为什么?我错过了中间件的某些方面吗?

标签: asp.net-coreasp.net-core-webapiasp.net-core-middleware

解决方案


推荐阅读