前言

 在程序中,经常需要处理比如 404500 ,502等错误,如果直接返回错误的调用堆栈的具体信息,显然大部分的用户看到是一脸懵逼的,你应该需要给用户返回那些看得懂的界面。比如,“当前页面不存在了” 等等,本篇文章主要来讲讲.NET-Core 中异常处理,以及如何自定义异常显示界面?,还有 如何定义自己的异常处理中间件?。

.NET-Core 中的异常处理

 让我们从下面这段代码讲起,写过.Net-Core 的应该不陌生,在 Startup 的 Configure 中定义异常处理的中间件。

if (env.IsDevelopment()){app.UseDeveloperExceptionPage();
}else{app.UseExceptionHandler("/error");
}

  上面两种情况分别是一个是使用自带的异常处理,另外一个是将错误异常的处理,进行自己处理。两种情况如下所示:

我在HomeController 中定义了一个Test Action如下所示(仅仅为了演示,并无实际意义)

//Controllerpublic string Test(int id){    if(id == 1){        return new System.NullReferenceException("It's not equals to 1, robert!");}  return "Bingo,Robert!";
}//Routingroutes.MapRoute(name: "Error",  template: "error/",defaults: new { controller = "Home", action = "error" }
);

 使用 localhost:{port}/home/test/2 的结果像下面这样

对我localhost:{port}/home/test/1 这样呢,在不同环境下是不一样的,具体如下所示:

  • UseDeveloperException

  • UseExceptionHandler

这些呢,就是比较平常的 .NET-Core 的处理方式。但是看不见StatusCode,发现没有,除了自定义的时候,默认时是不提供Status Code 的。这时候,就可以用到这个

UseStatusCodePages() 想要看源码的在这 StatusCodePagesExtension Source Code。

效果怎么样的呢?如下所示:

 这是默认的处理方式,看了源码我们知道,UseStatusCodePages 有4个重载。还可以自己定义,是不是感觉比前面的高级点,下面是自定义:具体就不演示了。

app.UseStatusCodePages(async context =>{context.HttpContext.Response.ContentType = "text/plain";  await context.HttpContext.Response.WriteAsync($"What's the statusCode you got is {context.HttpContext.Response.StatusCode}");
});app.UseStatusCodePages("text/plain","What's the statusCode you got is {0}");

 截止到上面为止,基本的异常处理其实已经介绍的差不多了。但是,总感觉那么普遍呢,好像还不够特殊,并且还满足不了我们的需求,我们想要自定义错误的处理方式。比如我们想要遇到 404 时就显示 404 界面。

定义异常处理中间件

 其实上面的自定义自己的异常处理时,其实已经可以做到我们需要的情况了。我们在Error Action 中对HttpContext.Response.StatusCode 进行判断,根据不同的StatusCode return 不同的View就可以了。但是为什么我们还需要定义特定处理的中间件,主要目的是为了其他项目服务的,如果你只有一个项目,一个站点,其实并没什么必要。但是如果有很多子站点时,还是需要考虑的一下的。

 模仿了一下 UseStatusCodePagesWithReExecute这个,写了一个

using System;using System.Collections.Generic;using System.Text;using Microsoft.AspNetCore.Builder;using System.Globalization;using System.Threading.Tasks;using Microsoft.AspNetCore.Diagnostics;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.Options;namespace MiddlewareDemo.CustomMiddleware{    /// <summary>/// Adds a StatusCodePages middleware to the pipeline. Specifies that the response body should be generated by /// re-executing the request pipeline using an alternate path. This path may contain a '{0}' placeholder of the status code./// </summary>/// <param name="app"></param>/// <param name="pathFormat"></param> //因为直接 处理404 所以就不给参数啦。/// <param name="queryFormat"></param>/// <returns></returns>public static class ErrorHandlerMiddlewareExtension{         public static IApplicationBuilder UseErrorHandler(            this IApplicationBuilder app,                    string pathFormat = "/error",            string queryFormat = null)        {                if (app == null){                          throw new ArgumentNullException(nameof(app));}                      return app.UseStatusCodePages(async context =>{                            if (context.HttpContext.Response.StatusCode == StatusCodes.Status404NotFound){                                  var newPath = new PathString(                        string.Format(CultureInfo.InvariantCulture, pathFormat, context.HttpContext.Response.StatusCode));                    var formatedQueryString = queryFormat == null ? null :                        string.Format(CultureInfo.InvariantCulture, queryFormat, context.HttpContext.Response.StatusCode);                                     var newQueryString = queryFormat == null ? QueryString.Empty : new QueryString(formatedQueryString);                                     var originalPath = context.HttpContext.Request.Path;                                   var originalQueryString = context.HttpContext.Request.QueryString;                    // Store the original paths so the app can check it.context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature(){OriginalPathBase = context.HttpContext.Request.PathBase.Value,OriginalPath = originalPath.Value,OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,});context.HttpContext.Request.Path = newPath;context.HttpContext.Request.QueryString = newQueryString;                                     try{                                           await context.Next(context.HttpContext);}                                     finally{context.HttpContext.Request.QueryString = originalQueryString;context.HttpContext.Request.Path = originalPath;context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(null);}}});}}
}

这样就会只处理404啦。

如下所示 :

最后分享一个 Re-execute vs Redirect 的一位大神的分析

  其实在 StatusCodePagesExtensions中还有两个方法,这两个方法也会比较实用,主要是用来当遇到异常,给你跳转到其他界面的。

//使用的话就像下面这样就可以啦app.UseStatusCodePagesWithReExecute("/error","?StatusCode={0}");app.UseStatusCodePagesWithRedirects("/error");//具体可以用哪些参数呢,可以去看源码,这里就不多介绍了。

这两个的虽然都可以得到我们想要的结果,但是过程差的有点多。先盗一下大神的两张图:

第一张是 Redirect的 :

下面一张是 ReExecute` 的

区别呢,我用Chrome Developer Console 来给你们展示一下,你们就明白啦。

这个是 redirect 的 ,很神奇吧,它返回的是200 ok. 由于是 redirect 所以 地址 redirect 到了 localhost:52298/error 。看Network可知,进行了两次请求,第一次,http://localhost:52298/home/testpage 时 返回302 Found. 我们知道这个是 404 的状态码,被 middleware “抓到”后,于是,我们再次发起请求, http://localhost:52298/error这个请求当然返回的状态码是 200 啦。所以我们在下图的结果中可以看见。200 OK。

302 : The 302 (Found) status code is used where the redirection is temporary or generally subject to change, such that the client shouldn't store and reuse the redirect URL in the future

下面的是ReExecute 的

结语

  如有陈述的不正确处,请多多评论指正。

文章推荐及参考链接

  • Use statusCodeWithReExecute and pic reference

  • StatusCodePagesExtensions Source Code

相关文章:

  • .NET Core 2.0 正式发布信息汇总

  • .NET Standard 2.0 特性介绍和使用指南

  • .NET Core 2.0 的dll实时更新、https、依赖包变更问题及解决

  • .NET Core 2.0 特性介绍和使用指南

  • Entity Framework Core 2.0 新特性

  • 体验 PHP under .NET Core

  • .NET Core 2.0使用NLog

  • 升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

  • 解决Visual Studio For Mac Restore失败的问题

  • ASP.NET Core 2.0 特性介绍和使用指南

  • .Net Core下通过Proxy 模式 使用 WCF

  • .NET Core 2.0 开源Office组件 NPOI

  • ASP.NET Core - Razor页面之Handlers处理方法

  • ASP.NET Core Razor页面 vs MVC

  • Razor Page–Asp.Net Core 2.0新功能  Razor Page介绍

  • ASP.Net Core 2.0中的Razor Page不是WebForm

原文地址:http://www.cnblogs.com/xiyin/p/7507405.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

Error Handling in ASP.NET Core相关推荐

  1. ASP.NET Core 运行原理剖析

    1.1. 概述 在ASP.NET Core之前,ASP.NET Framework应用程序由IIS加载.Web应用程序的入口点由InetMgr.exe创建并调用托管.以初始化过程中触发HttpAppl ...

  2. 加速ASP.NET Core WEB API应用程序。 第三部分

    深度重构和完善ASP.NET Core WEB API应用程序代码 (Deep refactoring and refinement of ASP.NET Core WEB API applicati ...

  3. ASP.NET Core Razor官方文档踩坑

    环境:ASP.NET Core 3.1 工具:VS2019 官方文档的起始页地址:教程:使用 ASP.NET Core 创建 Razor Pages Wb 应用 | Microsoft Learn 添 ...

  4. 服务器win2008 R2 x64 部署ASP.net core到IIS 并解决 HTTP Error 502.5 的问题

    1.发布网站 : 2.安装 vc_redist.x64  (Visual C++ Redistributable for Visual Studio 2015) 新装的系统没装的补丁,装过略过: 3. ...

  5. 在ASP.NET Core使用Middleware模拟Custom Error Page功能

    一.使用场景 在传统的ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAtt ...

  6. asp.net core .net 3.1 HTTP Error 500.30 ANCM In-Process Start Failure

    参考 https://go.microsoft.com/fwlink/?LinkID=2028265 HTTP Error 500.30 ANCM In-Process Start Failure 事 ...

  7. .net core发布到IIS上出现 HTTP Error 500.31 - Failed to load ASP.NET Core runtime

    错误提示: HTTP Error 500.31 - Failed to load ASP.NET Core runtime Common solutions to this issue: The sp ...

  8. asp.net core 5配置IIS报错 HTTP 错误 500.19 - Internal Server Error 错误代码 0x8007000d

    我的解决 走了不少歪路,最后发现是没有装 运行环境: 检查你的IIS>"模块">里是否 存在[AspNetCoreModuleV2]这个东西 如果没有,那么你就需要装 ...

  9. ASP.NET Core 中的 startup类

    原文地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup 下文: --Startup类 --Configure方法 ...

最新文章

  1. C++_泛型编程与标准库(二)
  2. go语言mysql视频_Go语言实战流媒体视频网站
  3. 爬虫---Beautiful Soup 通过添加不同的IP请求
  4. 认识 UART 接口
  5. Knockout中ViewModel与Model的互转
  6. php数组函数(分类基本数组函数,栈函数,队列)
  7. Java基础学习总结(38)——Lombok(消除冗长的 java 代码)的使用和原理及安装、入门使用
  8. matlab2c使用c++实现matlab函数系列教程-conj函数
  9. 乐视max2 刷入第三方recovery 然后刷入root 包 root
  10. C# 中文乱码,转成中文
  11. Linux 硬盘故障修复
  12. 解码h264和h265需要的cpu性能
  13. Excel 6位数字与MD5对照表 100000-999999
  14. html如何实现自动登录,Js实现下次自动登录功能
  15. 分享-IE游览器升级工具
  16. 计算机主机结构和名称图,计算机结构图
  17. [Mailbox]SIM卡中Alpha Identifier域解析
  18. C# 后台GC 的前因后果
  19. 20.04Ubuntu安装桌面系统详细教程
  20. php 公众号 群发,微信公众号【服务号】群发策略调整,并开通高级群发接口

热门文章

  1. Mybatis-Generator(MBG)教程与Idea的MBG插件
  2. linux centos7 root密码重置
  3. MFC Attach()函数和Detach()函数
  4. 透过表象看本质!?之二数据拟合
  5. 更新丨.NET 7 预览版2 中的 ASP.NET Core
  6. 【亲身经验】如何在 6 个月内成为“微软 MVP”
  7. 提的最多的数据库“索引”,先来简单了解一下
  8. Natasha 4.0 探索之路系列(四) 模板 API
  9. NET流行高性能JSON框架-Json.NET
  10. 我用 MySQL 干掉了一摞简历