在ASP.NET Core应用程序中,处理错误和异常是一个重要的部分,以确保用户在遇到问题时能获得清晰的反馈。本文将介绍如何通过中间件和控制器来实现自定义的错误页面,以便在发生HTTP状态码错误时提供更好的用户体验。
首先,需要创建一个空的ASP.NET Core项目,并更新Startup类以添加状态码页面的中间件。以下是配置中间件的代码示例:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePagesWithReExecute(
"/Errors/Index",
"?statusCode={0}");
app.UseMvcWithDefaultRoute();
}
}
在上述代码中,{0}将被替换为触发执行中间件的HTTP状态码。
接下来,需要添加一个Errors控制器来捕获状态码错误。以下是Errors控制器的代码示例:
public class ErrorsController : Controller
{
public IActionResult Index(int statusCode)
{
var feature = HttpContext.Features.Get();
ViewBag.StatusCode = statusCode;
ViewBag.OriginalPath = feature?.OriginalPath;
ViewBag.OriginalQueryString = feature?.OriginalQueryString;
return View();
}
}
Errors控制器的Index方法将获取状态码,并将其传递给视图,以便显示错误详情。
为了显示错误详情,需要为Errors控制器的Index方法添加一个视图。以下是视图的HTML代码示例:
<p>
状态码:
<b>
@ViewBag.StatusCode
</b>
</p>
<p>
原始路径:
<b>
@ViewBag.OriginalPath
</b>
</p>
<p>
原始查询字符串:
<b>
@ViewBag.OriginalQueryString
</b>
</p>
这个视图将显示状态码、原始路径和原始查询字符串,以便用户了解发生了什么错误。
为了测试错误处理,需要添加一个HomeController来返回不同的状态码。以下是HomeController的代码示例:
public class HomeController : Controller
{
public IActionResult Index() => View();
public IActionResult Throw404(int id) => StatusCode(404);
public IActionResult Throw412(int id) => StatusCode(412);
public IActionResult Throw500(int id) => StatusCode(500);
}
HomeController提供了不同的方法来模拟不同的HTTP状态码错误。
最后,需要为HomeController的Index方法添加一个视图。以下是视图的HTML代码示例:
<p>
已到达主页
</p>
<ul>
<li>
<a href="/Home/Throw404?id=1">
404 (未找到)
</a>
</li>
<li>
<a href="/Home/Throw412?id=2">
412 (前提条件失败)
</a>
</li>
<li>
<a href="/Home/Throw500?id=3">
500 (内部服务器错误)
</a>
</li>
</ul>
这个视图提供了几个链接,用户点击这些链接将触发不同的HTTP状态码错误,并显示Errors控制器的错误视图。
运行应用程序并点击主页视图中的链接,将看到Errors控制器的错误视图。值得注意的是,URL不会改变,这意味着用户仍然看到他们最初请求的URL。
异常处理中间件(如本文所讨论的)将捕获未处理的异常。但是,如果想要为个别HTTP状态码显示错误页面,那么框架提供了另一种中间件来实现这一目的。
在配置中间件时,可以选择重新执行或重定向请求。上述解决方案展示了重新执行的方式,服务器将重写请求。结果是URL反映了用户浏览的路径,而不是错误页面的路径。
另一种选择是在设置中间件时配置重定向:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePagesWithRedirects(
"/Errors/Index?statusCode={0}");
app.UseMvcWithDefaultRoute();
}