错误处理
分类: Asp.net Core入门 ◆ 标签: #Asp.Net core基础 #基础 #Web ◆ 发布于: 2023-06-04 20:39:26

本节我们来学习错误的处理。
Developer Exception Page
在开发的阶段打开UseDeveloperExceptionPage()
中间件。
例如:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
为了能够在开发阶段抓住足够多的异常或者错误,模板将这个中间件放在了最开始的地方,这个页面主要负责这些信息:
- Stack Trace
- 查询参数
- Cookie
- Header
Exception Handler page
在产线环境的时候,无法使用上述的中间件,我们需要使用另外一个中间件UseExceptionHandler
, 这个在产线使用的时候,框架首先会抓住和记录异常日志,然后在指定的路径上重新运行该请求,例如模板种的/Error
页面,要注意的是框架会使用原来的请求方法和数据在这个路径上运行,这样不要限定/Error的请求方法等等。
例如可以考虑在error page上创建多个方法,onGet, Onpost等等。
存取异常
使用接口IExceptionHandlerPathFeature
来存取异常以及原始的请求路径,只能在Exception Handler里用。
使用这个例子来看一下如何使用这个异常以及原始路径:
[ResponseCache(Duration=0, Location=ResponseCacheLocation.None, NoStore=true)] [IgnoreAntiforgeryToken] public class ErrorModel : PageModel { public string RequestId { get; set; } public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); public string ExceptionMessage { get; set; } private readonly ILogger<ErrorModel> _logger; public ErrorModel(ILogger<ErrorModel> logger) { _logger = logger; } public void OnGet() { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>(); if (exceptionHandlerPathFeature?.Error is FileNotFoundException) { ExceptionMessage = "File error thrown"; _logger.LogError(ExceptionMessage); } if (exceptionHandlerPathFeature?.Path == "/index") { ExceptionMessage += " from home page"; } } }
Exception Handler lambda
除了使用Exception Handler Page之外,还可以使用lambda表达式来处理这个。
例如:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;; context.Response.ContentType = "text/html"; await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n"); await context.Response.WriteAsync("ERROR!<br><br>\r\n"); var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>(); if (exceptionHandlerPathFeature?.Error is FileNotFoundException) { await context.Response.WriteAsync( "File error thrown!<br><br>\r\n"); } await context.Response.WriteAsync( "<a href=\"/\">Home</a><br>\r\n"); await context.Response.WriteAsync("</body></html>\r\n"); await context.Response.WriteAsync(new string(' ', 512)); }); }); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
Database error page
可以引入服务AddDatabaseDeveloperPageExceptionFilter
用来监视数据操作的错误。
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDatabaseDeveloperPageExceptionFilter(); services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddRazorPages(); }
另外还有Filter
和Model state errors
不过这些都会放在后面的高级部分来学些。我们这个部分还是以基础为主。