热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ASP.NETCore中文文档第三章原理(5)错误处理

原文:ErrorHandling作者:SteveSmith翻译:谢炀(Kiler)校对:高嵩(jack2gs)、何镇汐当你的ASP.NET应用发生错误的时候,你可以采用本文所述的各

原文:Error Handling
作者:Steve Smith
翻译:谢炀(Kiler)
校对:高嵩(jack2gs)、何镇汐

当你的ASP.NET应用发生错误的时候, 你可以采用本文所述的各种方法来处理这些问题。

章节:

  • 配置错误处理页面
  • 使用开发者异常页面
  • 配置状态码页面
  • 错误处理在CS交互模式下的限制
  • 服务器错误处理
  • Startup 错误处理
  • ASP.NET MVC 错误处理

查看或者下载示例代码

你在 Startup 类的 Configure() 方法中为每一个请求配置管道 (更多内容请参考 Application Startup)。 你可以轻松的添加一个仅仅适用于开发阶段的简单异常页面。只需要在项目中添加 Microsoft.AspNetCore.Diagnostics 依赖,并且添加一行代码到 Startup.csConfigure() 方法里面:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseIISPlatformHandler();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

以上代码包含一个检查,以确保添加调用 UseDeveloperExceptionPage 的环境是开发环境。这是一个好的实践,因为你通常情况下并不希望在应用程序已经处于生产环境的情况下,将你的应用程序的详细异常信息对外公开. 详细了解如何配置环境。
示例应用程序包括一个创建异常的简单机制的例子:

public static void HomePage(IApplicationBuilder app)
{
    app.Run(async (context) =>
    {
        if (context.Request.Query.ContainsKey("throw"))
        {
            throw new Exception("Exception triggered!");
        }
        var builder = new StringBuilder();
        builder.AppendLine("Hello World!");
        builder.AppendLine("");
        builder.AppendLine("");

        context.Response.COntentType= "text/html";
        await context.Response.WriteAsync(builder.ToString());
    });
}

如果请求中包含一个变量名为 throw 的非空查询字符串 (例如,路径: /?throw=true), 那么就会抛出一个异常。如果环境被设置为 Development , 开发者异常页面将会被显示:
ASP.NET Core 中文文档 第三章 原理(5)错误处理

当不在开发模式下, 建议使用 UseExceptionHandler 方法来配置一个错误处理路径:

app.UseExceptionHandler("/Error");

当Web请求中发生无法捕获异常的时候,开发者异常页面会显示有用的调试信息。页面包含几个选项卡页面来显示Web请求中引发的异常信息。 第一个选项卡页面包含错误堆栈跟踪信息:
ASP.NET Core 中文文档 第三章 原理(5)错误处理

第二个选项卡页面显示查询字符串信息,如果有的话:
ASP.NET Core 中文文档 第三章 原理(5)错误处理

在这个案例里面,你可以看到 throw 参数的值被传递到了请求。这个请求不包含任何COOKIEs,但是如果有任何COOKIEs,他们的值会显示在COOKIEs选项卡页面。你可以在最后一个选项卡页面查看到头信息:
ASP.NET Core 中文文档 第三章 原理(5)错误处理

在默认情况下,你的应用程序无法为Http状态码返回(例如:500 (服务器内部错误) or 404 (文件无法找到))提供一个富文本的HTTP状态码页面。你可以在 Configure 方法中加入一行 StatusCodePagesMiddleware 代码:

app.UseStatusCodePages();

在默认情况下,系统会为普通的http状态码添加一个非常简单纯文本的处理,例如,下面是404无法找到文件状态码返回的结果。
ASP.NET Core 中文文档 第三章 原理(5)错误处理

中间件提供不同的扩展方法,你也可以使用自定义lambda表达式来配置参数:

  app.UseStatusCodePages(cOntext=>
  context.HttpContext.Response.SendAsync("Handler, status code: " +
  context.HttpContext.Response.StatusCode, "text/plain"));

另外, 你也可以简单的传递一个内容类型和格式化字符串:

app.UseStatusCodePages("text/plain", "Response, status code: {0}");

中间件也能处理重定向请求 (无论是绝对路径还是相对路径), 把状态码作为URL的一部分进行传递:

app.UseStatusCodePagesWithRedirects("~/errors/{0}");

在上面的案例中, 客户端浏览器遇到 302 / Found状态码返回时,会重定向到指定的页面.
另外,中间件也提供设置一个新的路径字符串的方式来重新执行请求。

app.UseStatusCodePagesWithReExecute("/errors/{0}");

方法 UseStatusCodePagesWithReExecute 会返回原始的浏览器状态码页面,但是也会执行路径中指定的处理程序。

如果你需要对某些请求禁止状态码页面, 可以使用以下代码:

var statusCodePagesFeature = context.Features.Get();
if (statusCodePagesFeature != null)
{
  statusCodePagesFeature.Enabled = false;
}

Web应用在错误处理功能上因为断开HTTP请求和响应的特性有些特别的限制,有的应用程序,在你设计错误处理行为时请注意以下几点。

  1. 一旦响应文件头发送出去以后,你就无法再修改响应的状态码了,无论是任何异常页面或处理程序都无法执行。响应必须完成或者连接中断退出。
  2. 如果客户端在响应中期断开,你无法把当前响应的剩余内容发送给客户端。
  3. 在你的错误处理层之下,总是有可能存在有例外的一层。
  4. 不要忘了,错误处理页面也会产生异常. 生产环境异常页面采用纯静态页面是个不错的建议。

遵从上述建议将有助于确保您的应用程序保持响应,并且能很好地处理应用程序可能发生的异常。

除了你的应用程序中的错误处理逻辑,托管应用程序的服务器也将执行一些错误处理。如果服务器在头信息发送出去之前捕获到异常,它会发出不带主体的500内部服务器错误响应。如果在头文件发送出去之后捕获到异常必须关闭连接。那些不是被你的应用程序处理的请求将被服务器处理,并且发生的任何异常将被服务器的错误处理机制来处理。任何在你的应用程序里面配置好自定义错误页、错误处理中间件、过滤器都无法影响此行为。

处理异常最为棘手的地方是在你的应用程序启动的时候。只有承载层可以处理应用程序的启动过程中发生的异常。应用程序启动时发生的异常也会影响服务器的行为。例如,要启用SSL in Kestrel,有些必须用 KestrelServerOptions.UseHttps() 配置服务器。如果一个异常在 Startup 代码行之前发生,则默认情况下托管将捕获异常,并启动服务器,然后在非SSL端口上显示一个错误页面。如果有异常情况发生在该行执行之后, 则错误页面将通过HTTPS服务生效。

异常过滤器

异常过滤器可以在 MVC 应用程序的全局范围内或者每个Controller或者每个Action上进行配置。这些过滤器会处理controller action或其他过滤器的执行过程中发生的任何未处理的异常,其他情况则不会被调用。异常过滤器更多内容请见 过滤器。

小技巧
异常过滤器捕获MVC Action中发生的异常是很好的,但他们不如错误处理中间件灵活。一般情况下尽可能使用中间件,只有当在你需要在处理异常的时候需要特别指定某些MVC action的时候,过滤器才被建议使用。

处理模型状态错误

模型验证 在每个controller action被调用之前发生,Action方法的职责是检查 ModelState.IsValid 并作出适当的交互反应。在大部分情况下,特定的交互会返回特定的错误响应,最好详细说明模型验证失败的原因。

有些应用程序会选择遵循标准惯例处理模型验证错误,在这种情况下,过滤器可以作为某些策略的实现场所。您应该测试你的Action是否与有效和无效的模型状态有关联(了解更多有关 测试controller逻辑)的行为。


推荐阅读
  • 本文将带你快速了解 SpringMVC 框架的基本使用方法,通过实现一个简单的 Controller 并在浏览器中访问,展示 SpringMVC 的强大与简便。 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • [c++基础]STL
    cppfig15_10.cppincludeincludeusingnamespacestd;templatevoidprintVector(constvector&integer ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • Flutter中计算文本尺寸的方法
    在Flutter开发中,有时需要计算文本的宽度和高度。本文介绍了一种利用TextPainter类实现这一功能的方法。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • 在 .NET Core MVC 应用中,某页面在使用 IIS Express 和 IIS 进行调试时均能正常运行,但在发布后出现了 500 内部服务器错误。尽管在代码中添加了异常处理逻辑,但在 `return View(department)` 时并未捕获到任何异常,仅显示 500 错误,且没有任何其他详细的错误信息。这可能与发布环境的配置或依赖项有关,建议检查日志文件和配置设置以进一步诊断问题。 ... [详细]
  • Unity与MySQL连接过程中出现的新挑战及解决方案探析 ... [详细]
  • 在分析和解决 Keepalived VIP 漂移故障的过程中,我们发现主备节点配置如下:主节点 IP 为 172.16.30.31,备份节点 IP 为 172.16.30.32,虚拟 IP 为 172.16.30.10。故障表现为监控系统显示 Keepalived 主节点状态异常,导致 VIP 漂移到备份节点。通过详细检查配置文件和日志,我们发现主节点上的 Keepalived 进程未能正常运行,最终通过优化配置和重启服务解决了该问题。此外,我们还增加了健康检查机制,以提高系统的稳定性和可靠性。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
author-avatar
大西guoguo_120
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有