asp.net-core - 对于 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 正文!为什么?我错过了中间件的某些方面吗?
解决方案
推荐阅读
- java - XPath 结构不起作用
- javascript - 如何在d3.js中单击父节点上的子节点展开和折叠
- html - 将分页应用于 Angular js 中的表,其中 map 是我在 ng-repeat 中迭代的内容
- python - 在 for 循环中总结列表的元素
- php - 查询 ACF 转发器字段
- uitableview - 使用 Xcode 9.3 构建时 Tableview 不会滚动到底部
- php - 来自CORS预检通道的CORS标头“Access-Control-Allow-Headers”中缺少令牌“access-control-allow-origin”-反应js
- android - 有没有办法检测Android上的拨出电话是否以编程方式被回答或拒绝?
- laravel - 如何使用 Laravel 显示从其他用户收到的消息
- sonarqube - 一段时间后 sonarQube 异常关闭