我正在 .NET8 中创建一个新的 API 网站,这是 ASP.NET Core 的最新版本
在我的program.cs中我添加了这个:
builder.Services.AddExceptionHandler<ErrorHandler>();
app.UseExceptionHandler("/Home/Error");
如果出现异常,这确实会进入我的自定义错误处理类:
public class ErrorHandler : IExceptionHandler
我像这样访问我需要的额外数据:
private readonly ILogger<ErrorHandler> logger;
private readonly IHttpContextAccessor _httpContextAccessor;
public ErrorHandler(ILogger<ErrorHandler> logger, IHttpContextAccessor httpContextAccessor)
{
this.logger = logger;
this._httpContextAccessor = httpContextAccessor;
}
到目前为止一切顺利,但现在我尝试为我的日志获取一些数据:
private string GetErrorReport(Exception e)
{
StringBuilder sbErrorReport = new StringBuilder(1024);
try
{
HttpResponse response = _httpContextAccessor.HttpContext?.Response;
HttpRequest request = _httpContextAccessor.HttpContext?.Request;
string CurUrl = "";
string CurReferrer = "";
string formData = "";
string clientIP = "";
if(request != null)
{
CurUrl = request.GetEncodedPathAndQuery();
CurReferrer = request.Headers["Referer"].ToString();
if(request.Body != null) //is this the same as request.Form.ToString()?
{
using (StreamReader sr = new StreamReader(request.Body))
{
formData = sr.ReadToEnd();
}
}
if(request.HttpContext != null && request.HttpContext.Connection != null && request.HttpContext.Connection.RemoteIpAddress != null)
{
clientIP = request.HttpContext.Connection.RemoteIpAddress.ToString();
}
}
}
catch (Exception ex)
{
//nothing?
}
return sbErrorReport.ToString();
}
它们似乎都不起作用......
CurUrl 给出“/Home/Error”,而不是出现错误的原始 URL。 CurReferrer 给出有关标头不可用的错误。 formData 完全崩溃。 如果 ::1 对于 localhost 来说是正确的,则 clientIP 实际上似乎可以工作。
有什么想法可以最好地将包含所有这些详细信息的错误写入日志文件吗?
在错误处理程序操作中,您可以检索错误详细信息,如下所示:
var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
这将从当前上下文中检索错误信息。然后,您可以使用
exceptionHandlerFeature?.Error
检索实际错误。例如:
public string? ExceptionMessage { get; set; }
var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
var error = exceptionHandlerFeature.Error;
您还可以从
Path
的 exceptionHandlerFeature
属性中读取错误发生的位置(请求 URL),如下所示:
if (exceptionHandlerFeature?.Path == "/")
{
ExceptionMessage ??= string.Empty;
ExceptionMessage += " Page: Home.";
}
HttpContext.Connection.RemoteIpAddress
将为您提供客户端IP。事实上,你可以这样获取当前用户:
if (context.User.Identity is { IsAuthenticated: true })
userName = context.User.Identity.Name;
HttpContext.Request.Form
将为您提供表单数据。
Request.Headers["Referer"].ToString()
将为您提供引荐来源网址标题值。
顺便说一句,您可以选择使用内联处理程序进行错误处理,如下所示:
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
var errorCode = Guid.NewGuid().ToString();
var exceptionHandlerFeature =
context.Features.Get<IExceptionHandlerFeature>();
// do stuff
context.Response.Redirect("/error?customErrorCode=" + errorCode); // perform 302 redirection with error code in query string
});
});
app.UseHsts(); // you can configure any other non-development features in this if block too, like hsts or https redirection (note that you can do can set up these two in IIS too, although irrelevant)
}
请参阅 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0,了解有关使用内置 errir 在 ASP.NET Core 中进行错误处理的更多信息处理程序中间件。