本文将介绍在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请求。第一个选项卡包含一个堆栈跟踪

image.png

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

image.png

第三个是Cookies和Headers信息

image.png

提示:在任何你想要捕捉异常的中间件(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

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

image.png

修改 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错误代码页
}

再次访问不存在的页面

image.png

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

image.png

三使用MVC过滤器

//



/// 自定义全局异常过滤器

///

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把日志记录到本地文件后,系统对异常的处理就结束了。

开发环境下异常展示.gif

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

生产环境下异常展示.gif

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

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

什么是中间件?

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

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

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

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

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

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

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

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

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

    ///



    /// 自定义异常处理中间件

    ///

    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中构建路由的5种方法

    原文链接 :https://stormpath.com/blog/routing-in-asp-net-core 在ASP.NET Core中构建路由的5种方法 原文链接 :https://storm ...

  2. C#调用接口注意要点 socket,模拟服务器、客户端通信 在ASP.NET Core中构建路由的5种方法

    C#调用接口注意要点   在用C#调用接口的时候,遇到需要通过调用登录接口才能调用其他的接口,因为在其他的接口需要在登录的状态下保存Cookie值才能有权限调用, 所以首先需要通过调用登录接口来保存c ...

  3. ASP.NET Core中app.UseDeveloperExceptionPage和app.UseExceptionHandler方法有什么用

    在新建一个ASP.NET Core项目后,在项目Startup类的Configure方法中默认会添加两个方法的调用,app.UseDeveloperExceptionPage和app.UseExcep ...

  4. ASP.NET Core 释放 IDisposable 对象的四种方法

    本文翻译自<Four ways to dispose IDisposables in ASP.NET Core>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! IDispos ...

  5. 如何在asp.net mvc中添加自定义的HTML辅助种方法

    很久没在博客园发表文章了,今天来总结一下如何在asp.net mvc中添加自定义的HTML辅助方法.我们现在设计这么一个目前,利用自定义的HTML方法来渲染一个普通的img标记.直接进入主题吧: 首先 ...

  6. 如何在ASP.NET Core中自定义Azure Storage File Provider

    文章标题:如何在ASP.NET Core中自定义Azure Storage File Provider 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p ...

  7. ASP.NET Core中,UseDeveloperExceptionPage扩展方法会吃掉异常

    在ASP.NET Core中Startup类的Configure方法中,有一个扩展方法叫UseDeveloperExceptionPage,如下所示: // This method gets call ...

  8. 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获

    项目开发中的一些注意事项以及技巧总结   1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...

  9. 第十五节:Asp.Net Core中的各种过滤器(授权、资源、操作、结果、异常)

    一. 简介 1. 说明 提到过滤器,通常是指请求处理管道中特定阶段之前或之后的代码,可以处理:授权.响应缓存(对请求管道进行短路,以便返回缓存的响应). 防盗链.本地化国际化等,过滤器用于横向处理业务 ...

随机推荐

  1. ASP.NET Core 中间件(Middleware)(一)

    本文主要目标:记录Middleware的运行原理流程,并绘制流程图. 目录结构: 1.运行环境 2.Demo实践 3.源码追踪 4.AspnetCore内置middleware 一.运行环境 Visu ...

  2. 手把手搭建一套基于 Sentry 的异常监控系统

    手把手搭建一套基于 Sentry 的异常监控系统 Sentry 开源版 DevOps refs https://github.com/getsentry/sentry sentry-anomaly-m ...

  3. jQuery 使用注意事项 与 小技巧(tips)

    jQuery 使用注意事项 与 小技巧(tips) 1 $( document ).ready() https://learn.jquery.com/using-jquery-core/documen ...

  4. ADN vs CDN All In One

    ADN vs CDN All In One Netlify & JAMstack https://app.netlify.com/teams/xgqfrms/sites ADN Applica ...

  5. kahoot

    kahoot Make learning awesome! https://kahoot.it/ https://kahoot.com/ 我们的平台可让您在几分钟内轻松创建,共享和玩学习游戏或琐事测验 ...

  6. Windows 10 滚动截图工具

    Windows 10 滚动截图工具 Edge & Note & Clip https://www.runoob.com/docker/docker-architecture.html ...

  7. svg & stroke & style & class

    svg & stroke & style & class svg selected style methods style class, !important fill, st ...

  8. Redis 博文索引

    博文索引 Redis 对象与编码 Redis 持久化 Redis 主从复制 Redis 哨兵 Redis 缓存淘汰 Redis 集合统计 Redis 简介

  9. VAST助推NGK公链热度升温,日活超过以太坊!

    在区块链市场,如果说过去是比特币和以太坊的时代,那么现在和未来绝对是NGK的时代. NGK公链的出现,让区块链市场看到了新的希望.它不仅仅是开放的和可编程的,而且是低Gas燃耗的,以及创新共识机制的. ...

  10. React Native选择器组件-react-native-slidepicker

    react-native-slidepicker 一个纯 JavaScript 实现的的 React Native 组件,用于如地址,时间等分类数据选择的场景. github: https://git ...