startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync(ex.Message);
}
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
在上面的代码中,我注册了与管道开始时的中间件类似的中间件。ASP.NET核心将按照您放置请求的顺序处理任何请求,因此我的自定义中间件将首先运行请求。然而,反应是从下往上处理的。因此,在本例中,当在控制器(或任何位置)中引发异常时
UseDeveloperExceptionPage
或
UseExceptionHandler
将首先接收任何异常,处理它并将状态代码更改为500。
如果我们将顺序改为:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync(ex.Message);
}
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
现在,我们已经将处理程序注册为在请求的内置异常处理程序之后,但更重要的是,在响应的内置异常处理程序之前。因此,在本例中,当控制器抛出异常时,我们的处理程序将捕获它,处理它并将状态代码更改为我们想要的。其他异常处理程序将看不到异常(除非另一个中间件处理程序在我们之后抛出异常)。