在 ASP.NET Core 中记录异常信息
admin
2021-06-03本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP)
本文出自《从零开始学 ASP.NET Core 与 EntityFramework Core》目录
视频课程效果更佳:跨平台开发实战掌握 ASP.NET Core 与 EntityFramework Core
在 ASP.NET Core 中记录异常信息
在本章节中,我们将学习如何使用 ASP.NET Core 提供的 ILogger 接口记录我们自己的消息(Info),警告(Warnings)和异常(exceptions)信息。
当用户使用我们的应用程序时,如果有异常需要我们在某处记录异常。然后,开发人员可以查看异常日志,并在必要时提供修复。所以就需要记录异常信息,以了解在使用应用程序时生产服务器上发生了什么异常。
public class ErrorController:Controller
{
private ILogger<ErrorController> logger;
///<summary>
///注入ASP.NET Core ILogger服务。
///将控制器类型指定为泛型参数。
///这有助于我们进行确定哪个类或控制器产生了异常,然后记录它
///</summary>
///<param name="logger"></param>
public ErrorController(ILogger<ErrorController> logger)
{
this.logger = logger;
}
[AllowAnonymous]
[Route("Error")]
public IActionResult Error()
{
//获取异常详情信息
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
//LogError() 方法将异常记录作为日志中的错误类别记录
logger.LogError($"路径 {exceptionHandlerPathFeature.Path} " +
$"产生了一个错误{exceptionHandlerPathFeature.Error}");
return View("Error");
}
[Route("Error/{statusCode}")]
public IActionResult HttpStatusCodeHandler(int statusCode)
{
var statusCodeResult =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
switch (statusCode)
{
case 404:
ViewBag.ErrorMessage = "抱歉,你访问的页面不存在";
//LogWarning() 方法将异常记录作为日志中的警告类别记录
logger.LogWarning($"发生了一个404错误. 路径 = " +
$"{statusCodeResult.OriginalPath} 以及查询字符串 = " +
$"{statusCodeResult.OriginalQueryString}");
break;
}
return View("NotFound");
}
}
Error 和 NotFound 视图修改
因我们把消息信息改为记录到了日志中,所以我们调整我们的视图代码
Error 视图代码如下:
<h3>
程序请求时发生了一个内部错误,我们会反馈给团队,我们正在努力解决这个问题。
</h3>
<h5>请通过 ltm@ddxc.org 与我们取得联系</h5>
NotFound 视图代码修改为以下:
@{ ViewBag.Title = "页面不存在"; }
<h1>@ViewBag.ErrorMessage</h1>
<a asp-action="index" asp-controller="home">
点击此处返回首页
</a>
在 ASP.NET Core 中记录异常信息
两个简单的步骤来记录我们自己定义的消息(Info),警告(Warnings)和异常(exceptions)信息。
在需要日志记录功能的地方注入 ILogger 实例
可以指定 注入 ILogger 的类或控制器的类型作为 ILogger 泛型参数的参数。我们这样做是因为,可以将类或控制器的完整名称作为日志类别包含在日志输出中。
日志类别用于对日志消息进行分组。
由于我们已将 ErrorController 的类型指定为 ILogger 的泛型参数,因此 ErrorController 的完整名称也包含在下面的日志输出中。
private readonly ILogger<ErrorController> logger;
public ErrorController(ILogger<ErrorController> logger)
{
this.logger = logger;
}
为了让我们进行日志内容的显示操作更加的方便,我们打开appsettings.json
文件,在日志级别下面添加以下代码:
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Information"
}
},
然后重新进入我们的程序调试模式,您可以下面的图片中的日志记录信息。
我们在当前的日志中,显示了 Microsoft 级别的日志信息,因为我们通过在appsettings.json
文件中对日志级别进行了配置,通过配置的"Microsoft": "Information"
显示了Microsoft
的信息,我们也可以通过配置筛选过滤将"Microsoft": "Information"
更改为"Microsoft": "Warning"
。
然后重新进入调式模式,运行后,我们的调试输出窗口为空白。这是我们人为进行了过滤不打印出这些内容。
LogError() 方法将异常记录到日志中的错误分组中。
//LogError() 方法将异常记录到日志中的错误分组中。
logger.LogError($"路径 {exceptionHandlerPathFeature.Path} " +
$"产生了一个错误{exceptionHandlerPathFeature.Error}");
下面是 LogError() 方法生成的日志:
我们可以通过访问http://localhost:5160/home/details/1
进行触发我们的Waring
警告,因为我们在 Details.cshtml 中,写了一行抛出异常的代码。
public ViewResult Details(int? id)
{
throw new Exception("在Details视图中抛出异常");
//其他代码
}
触发后的结果如下:
我们可以获取到所有的完整错误日志信息,从我们的ErrorController
中,帮我们拦截到了具体到哪个类文件,以及哪行代码出错,以及报错的信息。这样帮助我们进行程序的定位是很有效的。
而能看到这些错误信息是因为我们在ErrorController
中的Error
操作方法中,添加的
logger.LogError($"路径 {exceptionHandlerPathFeature.Path} " +
$"产生了一个错误{exceptionHandlerPathFeature.Error}");
日志记录代码,帮助我们拦截到的错误信息。
StudentManagement.Controllers.ErrorController:Error: 路径/home/details/1 产生了一个错误System.Exception: 在Details视图中抛出异常
at StudentManagement.Controllers.HomeController.Details(Int32 id) in D:\CodeManager\aiabpedu\ASP.NET -core-mvc-2019\src\new\StudentManage\Controllers\HomeController.cs:line 43
at lambda_method(Closure , Object , Object[] )
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
现在我们尝试访问一个 URL,这个 URL 和我们的路由完全不匹配如http://localhost:5160/market/food/1?eat=apple
。
运行后,我们可以看到因为是不存在的路由匹配,所以进入的是ErrorController
中的HttpStatusCodeHandler
操作方法,产生的日志记录信息为:
StudentManagement.Controllers.ErrorController:Warning: 发生了一个404错误. 路径 =/market/food/1 以及查询字符串 = ?eat=apple
提示错误级别为Warning
级别的。这是因为我们的代码中指定该级别的错误为Waring
,同时帮我们将按照我们自定义的规则给处理完毕,完整运行图片,参考下图。
文章说明
如果您觉得我的文章质量还不错,欢迎打赏,也可以订阅我的视频哦
未得到授权不得擅自转载本文内容,52abp.com 保留版权
感谢您对我的支持