经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
asp.net core之异常处理
来源:cnblogs  作者:饭勺oO  时间:2023/8/4 9:02:29  对本文有异议

在开发过程中,处理错误是一个重要的方面。ASP.NET Core提供了多种方式来处理错误,以确保应用程序的稳定性和可靠性。

TryCatch

TryCatch是最常见也是最基础的一种异常处理方式,只需要用TryCatch把执行代码包起来,即可捕获异常。
格式如下:

  1. try
  2. {
  3. // 执行操作
  4. doAny();
  5. }
  6. catch (Exception ex)
  7. {
  8. // 处理异常
  9. doExceptionHandling();
  10. }

这属于最基本的异常处理方式,这里就不加上实操代码了。本文主要讲解asp.net core中的其他异常处理方式。

开发人员异常页

ASP.NET Core Web应用在以下情况下默认启用开发人员异常页,用于显示未经处理的请求异常的详细信息。
ASP.NET Core 应用在以下情况下默认启用开发人员异常页:

  • 在开发环境中运行。
  • 使用当前模板创建的应用,即使用 WebApplication.CreateBuilder。 使用 WebHost.CreateDefaultBuilder 创建的应用必须通过在 Configure 中调用 app.UseDeveloperExceptionPage 来启用开发人员异常页。

开发人员异常页运行在中间件管道的前面部分,以便它能够捕获随后中间件中抛出的未经处理的异常。
这里我们新建一个MVC项目,使用WebApplication.CreateBuilder,所以不需要显式调用app.UseDeveloperExceptionPage 来启用开发人员异常页,在HomeController中添加一个Thorw方法直接抛出异常:

  1. using LearnException.Models;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System.Diagnostics;
  4. namespace LearnException.Controllers
  5. {
  6. public class HomeController : Controller
  7. {
  8. private readonly ILogger<HomeController> _logger;
  9. public HomeController(ILogger<HomeController> logger)
  10. {
  11. _logger = logger;
  12. }
  13. public IActionResult Index()
  14. {
  15. return View();
  16. }
  17. public IActionResult Privacy()
  18. {
  19. return View();
  20. }
  21. public IActionResult Throw()
  22. {
  23. throw new Exception("Customer Excetion");
  24. }
  25. [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
  26. public IActionResult Error()
  27. {
  28. return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
  29. }
  30. }
  31. }

启动项目,然后访问/Home/Throw路径。
image.png
可以看到这个页面可以看到我们的详细错误信息,包括异常栈,Query参数, Cookies参数,HTTP请求Headers信息以及路由信息。
这个页面在开发阶段,非常利于我们排查错误。

异常处理程序页

由于我们的一些异常信息不便在非开发环境展示,所以在非开发环境,我们需要一个异常处理程序页。
若要为生产环境配置自定义错误处理页,请调用 UseExceptionHandler。 此异常处理中间件:

  • 捕获并记录未经处理的异常。
  • 使用指示的路径在备用管道中重新执行请求。 如果响应已启动,则不会重新执行请求。 模板生成的代码使用 /Home/Error 路径重新执行请求。

在我们创建的MVC模板的Program中,有这样的代码:

  1. if (!app.Environment.IsDevelopment())
  2. {
  3. app.UseExceptionHandler("/Home/Error");
  4. }

表示在非开发环境中启用此异常处理中间件。这里的"/Home/Error"表示跳转到该路由。该路由为异常处理页面。
在模板Views/Shared下面我们可以看到一个Error.cshtml,和Models下面有一个ErrorViewModel,这就是默认的异常处理程序页。
在上面HomeController的代码中我们可以看到一个Error的Action,此Action指向Error页面。我们试试直接起启用app.UseExceptionHandler("/Home/Error"),放开在非开发环境才使用的条件:

  1. //if (!app.Environment.IsDevelopment())
  2. //{
  3. app.UseExceptionHandler("/Home/Error");
  4. //}

分别请求/Home/Error和/Home/Throw路径
image.png
image.png
可以看到/Home/Throw也是跳转到Error页面,但是没有详细的异常信息。

自定义异常处理程序页

除了上述的方式,我们在需要自定义异常处理程序页时,可以使用app.UseExceptionHandler的另一个重载方法:

  1. app.UseExceptionHandler(exceptionHandlerApp =>
  2. {
  3. exceptionHandlerApp.Run(async context =>
  4. {
  5. context.Response.StatusCode = StatusCodes.Status500InternalServerError;
  6. // using static System.Net.Mime.MediaTypeNames;
  7. context.Response.ContentType = Text.Plain;
  8. await context.Response.WriteAsync("An exception was thrown.");
  9. var exceptionHandlerPathFeature =
  10. context.Features.Get<IExceptionHandlerPathFeature>();
  11. if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
  12. {
  13. await context.Response.WriteAsync(" The file was not found.");
  14. }
  15. if (exceptionHandlerPathFeature?.Path == "/")
  16. {
  17. await context.Response.WriteAsync(" Page: Home.");
  18. }
  19. });
  20. });

在上面代码中exceptionHandlerApp是一个IApplicationBuilder,本质是添加一个终结点中间件去处理响应内容,上面内容包括了修改Http响应的StatusCode,ContentType,以及响应内容。
我们在HomeController中继续添加一个FileNotFound的Action。

  1. public IActionResult FileNotFound()
  2. {
  3. throw new FileNotFoundException();
  4. }

启动项目,分别请求/Home/Throw和/Home/FileNotFound。
image.png
image.png
可以看到,响应内容和我们配置的一致。
由上面表现,其实我们可以想到,如何自定义一个异常处理中间件。

  1. public class MyExceptionMiddleware
  2. {
  3. private readonly RequestDelegate _next;
  4. public MyExceptionMiddleware(RequestDelegate next)
  5. {
  6. _next = next;
  7. }
  8. public async Task Invoke(HttpContext context)
  9. {
  10. try
  11. {
  12. await _next(context);
  13. }
  14. catch (Exception ex)
  15. {
  16. context.Response.StatusCode = StatusCodes.Status500InternalServerError;
  17. // using static System.Net.Mime.MediaTypeNames;
  18. context.Response.ContentType = Text.Plain;
  19. await context.Response.WriteAsync("An exception was thrown.");
  20. if (ex is FileNotFoundException)
  21. {
  22. await context.Response.WriteAsync(" The file was not found.");
  23. }
  24. }
  25. }
  26. }

在Program添加中间件

  1. app.UseMiddleware<MyExceptionMiddleware>();

image.png
可以看到,效果完全一致。
除此之外,我们还有使用ExceptionFilter的方式去处理异常,只要实现实现 IExceptionFilter 或 IAsyncExceptionFilter即可。
添加一个MyExceptionFilter

  1. public class MyExceptionFilter : IAsyncExceptionFilter
  2. {
  3. public async Task OnExceptionAsync(ExceptionContext context)
  4. {
  5. context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
  6. // using static System.Net.Mime.MediaTypeNames;
  7. context.HttpContext.Response.ContentType = Text.Plain;
  8. await context.HttpContext.Response.WriteAsync("An exception was thrown. by MyExceptionFilter");
  9. context.ExceptionHandled = true;
  10. }
  11. }

在HomeController添加一个Filter的Action。

  1. [TypeFilter(typeof(MyExceptionFilter))]
  2. public IActionResult Filter()
  3. {
  4. throw new Exception("MyExceptionFilter Excetion");
  5. }

启动项目,访问/Home/Filter路径。
image.png
可以看到效果跟预想的一致。

ASP.NET Core提供了多种方式来处理错误。开发人员可以根据具体的需求选择适合的错误处理方式,并进行相应的处理和响应。通过合理的错误处理,可以提高应用程序的稳定性和可靠性,提供更好的用户体验。

欢迎进群催更。

image.png

原文链接:https://www.cnblogs.com/fanshaoO/p/17603536.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号