本文将介绍在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. python(三)——while语句

    while死循环 #!/usr/bin/env python #-*- coding:utf8 -*- import time while 1 == 1: print('Ok',time.time() ...

  2. 3-开发共享版APP(接入指南)-设备接入说明:使用隐藏配置

    https://www.cnblogs.com/yangfengwu/p/11273226.html 该APP安装包下载链接: http://www.mnif.cn/appapk/IotDevelop ...

  3. java如何判断溢出

    public int reverse2(int x) { double ans=0; int flag=1; if(x<0){ flag=-1; } x=x*flag; while(x>0 ...

  4. 【JZOJ6206】【20190610】二分图边染色

    题目 ​ 对一个二分图的边染色,满足有相同端点的边的颜色一定不同; ​ 设最优染色为\(C\) ,你的染色为\(X\),只需要满足$ X \le 2^ {\lceil log  C \rceil }$ ...

  5. mysql 修改字段名称以及长度

    //修改字段长度 alter table table1 modify name ); //修改字段名称以及长度 alter table table1 change name name_new ); a ...

  6. 第10组alpha冲刺(2/4)

    队名:凹凸曼 组长博客 作业博客 组员实践情况 童景霖 过去两天完成了哪些任务 文字/口头描述 继续学习Android studio和Java 完善项目APP原型 展示GitHub当日代码/文档签入记 ...

  7. 关于 Javascript 学习,有哪些好的博客或者网站推荐?

    知乎社区:http://www.zhihu.com/question/19651401 Mozilla开发者网络社区:https://developer.mozilla.org/zh-CN/ moze ...

  8. shell中$(( ))、$( )、``与${ }的区别

    转 :shell $(( )).$( ).``与${ }的区别 $( )与` `(反引号)命令替换 在bash中,$( )与` `(反引号)都是用来作命令替换的.命令替换与变量替换差不多,都是用来重组 ...

  9. 为什么GPU不能代替CPU?

    gpu就是并行处理强大, cpu很多功能gpu都没有. 什么指令流水化, 多进程管理之类的. gpu没有多少自主处理指令的能力, 基本是指令靠cpu 计算靠gpu.GPU工作原理是cpu 处理指令,遇 ...

  10. Python17个常用内置模块总结

    Python17个常用内置模块总结 1.getpass 2.os 3.sys 4.subprocess 5.hashlib 6.json 7.pickle 8.shutil 9.time 10.dat ...