try { // 执行操作 doAny(); } catch (Exception ex) { // 处理异常 doExceptionHandling(); }这属于最基本的异常处理方式,这里就不加上实操代码了。本文主要讲解asp.net core中的其他异常处理方式。
2.使用当前模板创建的应用,即使用 WebApplication.CreateBuilder。 使用 WebHost.CreateDefaultBuilder 创建的应用必须通过在 Configure 中调用 app.UseDeveloperExceptionPage 来启用开发人员异常页。
using LearnException.Models; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; namespace LearnException.Controllers { public class HomeController : Controller { // 堆代码 duidaima.com private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger) { _logger = logger; } public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } public IActionResult Throw() { throw new Exception("Customer Excetion"); } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } }启动项目,然后访问/Home/Throw路径。
if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); }表示在非开发环境中启用此异常处理中间件。这里的"/Home/Error"表示跳转到该路由。该路由为异常处理页面。在模板Views/Shared下面我们可以看到一个Error.cshtml,和Models下面有一个ErrorViewModel,这就是默认的异常处理程序页。在上面HomeController的代码中我们可以看到一个Error的Action,此Action指向Error页面。我们试试直接起启用app.UseExceptionHandler("/Home/Error"),放开在非开发环境才使用的条件:
//if (!app.Environment.IsDevelopment()) //{ app.UseExceptionHandler("/Home/Error"); //}分别请求/Home/Error和/Home/Throw路径
可以看到/Home/Throw也是跳转到Error页面,但是没有详细的异常信息。
app.UseExceptionHandler(exceptionHandlerApp => { exceptionHandlerApp.Run(async context => { context.Response.StatusCode = StatusCodes.Status500InternalServerError; // using static System.Net.Mime.MediaTypeNames; context.Response.ContentType = Text.Plain; await context.Response.WriteAsync("An exception was thrown."); var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>(); if (exceptionHandlerPathFeature?.Error is FileNotFoundException) { await context.Response.WriteAsync(" The file was not found."); } if (exceptionHandlerPathFeature?.Path == "/") { await context.Response.WriteAsync(" Page: Home."); } }); });在上面代码中exceptionHandlerApp是一个IApplicationBuilder,本质是添加一个终结点中间件去处理响应内容,上面内容包括了修改Http响应的StatusCode,ContentType,以及响应内容。
public IActionResult FileNotFound() { throw new FileNotFoundException(); }启动项目,分别请求/Home/Throw和/Home/FileNotFound。
可以看到,响应内容和我们配置的一致。由上面表现,其实我们可以想到,如何自定义一个异常处理中间件。
public class MyExceptionMiddleware { private readonly RequestDelegate _next; public MyExceptionMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { context.Response.StatusCode = StatusCodes.Status500InternalServerError; // using static System.Net.Mime.MediaTypeNames; context.Response.ContentType = Text.Plain; await context.Response.WriteAsync("An exception was thrown."); if (ex is FileNotFoundException) { await context.Response.WriteAsync(" The file was not found."); } } } }在Program添加中间件
app.UseMiddleware<MyExceptionMiddleware>();
public class MyExceptionFilter : IAsyncExceptionFilter { public async Task OnExceptionAsync(ExceptionContext context) { context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; // using static System.Net.Mime.MediaTypeNames; context.HttpContext.Response.ContentType = Text.Plain; await context.HttpContext.Response.WriteAsync("An exception was thrown. by MyExceptionFilter"); context.ExceptionHandled = true; } }在HomeController添加一个Filter的Action。
[TypeFilter(typeof(MyExceptionFilter))] public IActionResult Filter() { throw new Exception("MyExceptionFilter Excetion"); }启动项目,访问/Home/Filter路径。