本文将介绍在ASP.Net Core中处理异常的几种方法

  • 1使用开发人员异常页面(The developer exception page)
  • 2配置HTTP错误代码页 Configuring status code pages
  • 3使用MVC过滤器 ExceptionFilter
  • 4 自定义异常捕获中间件 Middleware

一使用开发人员异常页面(The developer exception page)

配置你的程序使其在发生异常时详细的展示异常信息

  • 安装Microsoft.AspNetCore.Diagnostics NuGet package

    .net core 2.0中包含Microsoft.AspNetCore.All,这里面包含了Microsoft.AspNetCore.Diagnostics,无需自安装。
  • 在Startup.cs 上添加对exception page的使用Configure method in the Startup class:
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();//使用异常记录页面
}

在控制器中抛一个异常:

   public class HomeController : Controller
{ public IActionResult Index()
{
throw new Exception();
return View();
}
}

在开发环境下运行,异常展示页面包含几个标签展示异常信息和HTTP请求。第一个选项卡包含一个堆栈跟踪

它下一个选项卡显示查询字符串参数,如果有的话。



第三个是Cookies和Headers信息

提示:在任何你想要捕捉异常的中间件(middleware)之前注册UseDeveloperExceptionPage 比如 app.UseMvc.

一般在项目开发中,UseDeveloperExceptionPage展示异常详情信息对开发过程很有帮助,但在项目发布出去以后,在系统发生异常时更明智的是向用户展示一个静态的错误页面。这时就要做如下更改了:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//判断是否是开发环境
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
}

依据上面代码, app.UseExceptionHandler("/error");在生产环境下,发生系统错误时,跳转到错误页面

二配置HTTP错误代码页 Configuring status code pages

如果访问项目上一个不存在的页面,会如下显示:

修改 Startup.Configure,使其能够使用HTTP错误代码页

       public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
//开发环境异常处理
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
//生产环境异常处理
app.UseExceptionHandler("/Home/Error");
}
app.UseStatusCodePages();//使用HTTP错误代码页
}

再次访问不存在的页面

app.UseStatusCodePages支持多种扩展方法。其中一个方法接受一个lambda表达式:

app.UseStatusCodePages(async context =>
{
context.HttpContext.Response.ContentType = "text/plain";
await context.HttpContext.Response.WriteAsync(
"Status code page, status code: " +
context.HttpContext.Response.StatusCode);
});

还可以跳转到指定页面,并附加Response.StatusCode

app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");

占位符{0}在这代表Response.StatusCode 如:404

三使用MVC过滤器

// <summary>
/// 自定义全局异常过滤器
/// </summary>
public class GlobalExceptionFilter : IExceptionFilter
{ readonly ILoggerFactory _loggerFactory;//采用内置日志记录
readonly IHostingEnvironment _env;//环境变量
public GlobalExceptionFilter(ILoggerFactory loggerFactory, IHostingEnvironment env)
{
_loggerFactory = loggerFactory;
_env = env;
} public void OnException(ExceptionContext context)
{
var controller = context.ActionDescriptor;
ILog log = LogManager.GetLogger(Startup.Repository.Name, controller.ToString());//初始化Log4net日志
#region 记录到内置日志
//var logger = _loggerFactory.CreateLogger(context.Exception.TargetSite.ReflectedType);
//logger.LogError(new EventId(context.Exception.HResult),
//context.Exception,
//context.Exception.Message);
#endregion
if (_env.IsDevelopment())
{
log.Error(context.Exception.ToString());
//var JsonMessage = new ErrorResponse("未知错误,请重试");
//JsonMessage.DeveloperMessage = context.Exception;
//context.Result = new ApplicationErrorResult(JsonMessage);
//context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
//context.ExceptionHandled = true;
}
else
{
log.Error(context.Exception.ToString());
context.ExceptionHandled = true;
context.Result=new RedirectResult("/home/Error");
}
}
public class ApplicationErrorResult : ObjectResult
{
public ApplicationErrorResult(object value) : base(value)
{
StatusCode = (int)HttpStatusCode.InternalServerError;
}
}
public class ErrorResponse
{
public ErrorResponse(string msg)
{
Message = msg;
}
public string Message { get; set; }
public object DeveloperMessage { get; set; }
}
}
}

使用OnException方法,当异常发生时,调用这个方法。

在上面代码中,根据项目环境的不同,分开处理异常。

  • 当开发环境中,通过Log4net把日志记录到本地文件中。再这里注释了一句很重要代码context.ExceptionHandled = true;//代表异常已经处理,context.ExceptionHandled 代表异常是否处理,不是true时,异常记录到日志文件中后,系统对异常的处理并未结束,如果这时系统使用了开发人员异常页面(The developer exception page),系统在页面上详细展示系统异常信息。若果context.ExceptionHandled为true,异常通过Log4net把日志记录到本地文件后,系统对异常的处理就结束了。

  • 生产环境下,通过Log4net把日志记录到本地文件中后,context.ExceptionHandled = true;系统处理异常结束,让系统跳转到静态错误页。

四自定义异常捕获中间件 Middleware

对于一些非MVC引起的异常,MVC过滤器是不能捕获异常的。

什么是中间件?

中间件是一种组装到系统应用程序的请求管道用来处理请求和相应的框架。它的各个构成:

1) 在程序管道中是否选择将请求传递给下一个组件。

2)可以在系统请求管道的下一个中间件的执行的前面或者后面处理请求和相应

一个委托请求被用来构建请求管道。这个委托请求用来处理每一个HTTP请求。

委托请求使用方法Run,Map 和使用Use方法的扩展方法来配置

自己可以指定创建一个匿名的委托请求in-iline,也可以将将其定义在一个可重用的类里面。

这些可重用的类和in-line匿名方法就称为中间件,或者中间组件。

在请求管道中的每一个中间件的任务就是调用下一个中间件,特定场景下也可以越过下一个中间件直接返回结果。

下面是一个自定义ExceptionHandlingMiddleware中间件的过程,当捕获到异常时,存到日志中。

    /// <summary>
/// 自定义异常处理中间件
/// </summary>
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next; public ExceptionHandlingMiddleware(RequestDelegate next)
{
_next = next;
} public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
var statusCode = context.Response.StatusCode;
await HandleExceptionAsync(context, ex.ToString());
}
}
private Task HandleExceptionAsync(HttpContext context, string msg)
{
HandleExceptionHelper hannd = new HandleExceptionHelper();
hannd.log.Error(msg);//记录到日志文件
return context.Response.WriteAsync("ERROR");
}
}

在定义一个异常的中间件,并抛一个异常,用ExceptionHandlingMiddleware捕获异常

 app.Use(async (context, next) =>
{
throw new Exception();
await next.Invoke();
});

Asp.Net Core异常处理的更多相关文章

  1. ASP.NET Core 异常处理与日志记录

    1. ASP.NET Core 异常处理与日志记录 1.1. 异常处理 1.1.1. 异常产生的原因及处理 1.1.2. ASP.NET Core中启动开发人员异常页面 1.2. 日志记录 1.2.1 ...

  2. Asp.Net Core异常处理整理

    目前版本是Asp.Net Core v1.1,这个版本的感觉对Http请求中的错误处理方便不是很完善. 没有HttpException异常类,不能在任何的地方自由的抛出对应的异常状态. 一.默认的异常 ...

  3. 深入探究ASP.NET Core异常处理中间件

    前言     全局异常处理是我们编程过程中不可或缺的重要环节.有了全局异常处理机制给我们带来了很多便捷,首先我们不用满屏幕处理程序可能出现的异常,其次我们可以对异常进行统一的处理,比如收集异常信息或者 ...

  4. ASP.NET Core ---异常处理

    一.局部异常处理: 在Action里面catch 二.全局异常处理: 1.默认的异常处理配置: 默认配置在StartUp文件的Configure中注册错误处理,显示开发者错误页面: public vo ...

  5. 我的asp.net core目录

    推荐 Asp.NETCore轻松学系列阅读指引目录(asp.net core 2.2) 官方文档翻译 http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore- ...

  6. Asp.Net Core 404处理

    在使用Asp.Net Core Mvc时 404处理整理如下 一.自带404状态处理 1.控制器视图子弹404视图 NotFoundResult,NotFoundObjectResult // // ...

  7. Asp.Net Core 文件上传处理

    本文主要介绍后台接收处理 1.在使用控制器接收 : [HttpPost] : public IActionResult UploadFiles(IList<IFormFile> files ...

  8. Asp.Net Core获取当前上下文对象

    HttpContext简介 .Net Core中的HttpContext上下文是个抽象类,命名空间为Microsoft.AspNetCore.Http 所在程序集 \netstandard2.0\Mi ...

  9. ASP.NET Core MVC 中设置全局异常处理方式

    在asp.net core mvc中,如果有未处理的异常发生后,会返回http500错误,对于最终用户来说,显然不是特别友好.那如何对于这些未处理的异常显示统一的错误提示页面呢? 在asp.net c ...

随机推荐

  1. 【转载】Visual Studio(VS) F12 查看DLL源代码

    https://www.cnblogs.com/zhaoqingqing/p/6751757.html esharper官网:https://www.jetbrains.com/resharper/ ...

  2. dbt 0.14.0 试用

    dbt 0.14.0 在最近已经发布了,dbt server 的还是很不错的特性,以下安装试用下几个新功能 环境准备 安装 如果没有安装的: pip install dbt 已经安装的: pip in ...

  3. ping fping

    通过ping来监测对端网络状态 ping fpinf在windows和linux上的参数是不同的,返回的结果也是不同的 在网络连通性监测方面用的比较多,在py go中调用命令,对返回的结果使用正则来在 ...

  4. 洛谷 P1522 牛的旅行 Cow Tours 题解

    P1522 牛的旅行 Cow Tours 题目描述 农民 John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧区通过任何路径都不 ...

  5. 前端微信小程序仿菜谱精灵

    需求描述及交互分析 设计思路和相关知识点 底部标签导航设计 幻灯片轮播效果设计 菜谱专题列表显示设计 菜谱专题详情设计 菜谱分类设计 幻灯片轮播效果动态切换展示一些美食图片 若本号内容有做得不到位的地 ...

  6. Android Studio一直显示Building“project name”Gradle project info问题详解

    关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 本篇文章同步微信公众号  欢迎大家关注我的微信公众号:「醉翁猫咪」 Android Studio一直显示 Building&quo ...

  7. 原创:搜索排序算法之自定义性能优良的PriorityQueue(与Python的heap比较)

    前几天写了一篇关于"史上对BM25模型最全面最深刻解读以及lucene排序深入解读"的博客,lucene最后排序用到的思想是"从海量数据中寻找topK"的时间空 ...

  8. Exception in thread "main" java.lang.IllegalStateException: Failed to read 问题解决

    开发中偶尔遇到这样的问题:Exception in thread "main" java.lang.IllegalStateException: Failed to read .. ...

  9. 设置win 10 软件开机启动

    C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 将快捷方式粘贴进去即可

  10. FormData实现文件上传

    我用到FormData传输的使用场景:vant UI组件里面 的图片上传这块,需要调用后台的图片上传接口,使用的是FormData方式上传的 https://www.cnblogs.com/hutuz ...