[转]Create Custom Exception Filter in ASP.NET Core
本文转自:http://www.binaryintellect.net/articles/5df6e275-1148-45a1-a8b3-0ba2c7c9cea1.aspx
In my previous article I explained how errors in an ASP.NET Core web application can be dealt with using middleware. I also mentioned that time that you can also use exception filters to handle errors. In this article I will explain how to do just that.
In ASP.NET MVC 5 you used the [HandleError] attribute and OnException() controller method to deal with exceptions that arise in the actions of a controller. In ASP.NET Core the process is bit different but the overall concept is still the same. As you are probable aware of, filters sit in the ASP.NET Core pipeline and allow you to execute a piece of code before or after an action execution. To understand how errors can be handled in ASP.NET Core let's create an exception filter called HandleException and then try to mimic the behavior of [HandleError] of ASP.NET MVC 5.
Begin by creating a new ASP.NET web application. Then add a class to it named HandleExceptionAttribute. This class needs to inherit from ExceptionFilterAttribute base class. The complete code of this class is shown below:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ViewFeatures; .... ....public class HandleExceptionAttribute : ExceptionFilterAttribute {public override void OnException(ExceptionContext context){var result = new ViewResult { ViewName = "Error" };var modelMetadata = new EmptyModelMetadataProvider();result.ViewData = new ViewDataDictionary(modelMetadata, context.ModelState);result.ViewData.Add("HandleException", context.Exception);context.Result = result;context.ExceptionHandled = true;} } }
The HandleExceptionAttribute class overrides the OnException() method of t he base class. The OnException() method is called only when there is an unhandled exception in an action. Inside, we create a ViewResult object that represents the custom error page. It is assumed that the view representing the custom error page is Error.cshtml. Later we will write some code to remove this hard-coding.
Then the code creates an empty object of EmptyModelMetadataProvider class. This is required because we need to initialize the ViewData of the request and add exception details in it. Then ViewData property of the ViewResult is assigned to a new ViewDataDictionary object. While creating the ViewDataDictionary the IModelMetadataProvider object created earlier is passed to the constructor along with the context's ModelState.
We would like to store the exception details into the ViewData so that the Error view can retrieve them and possibly display on the page. To facilitate this HandleException key is added to the ViewData. The exception being thrown can be obtained using context's Exception property.
Then Result property of context is set to the ViewResult we just configured. Finally, ExceptionHandled property is set to true to indicate that the exception need not be bubbled up any further.
Now open the HomeController and decorate the Index() action with the [HandleException] attribute.
[HandleException] public IActionResult Index() {throw new Exception("This is some exception!!!");return View(); }
Also add Error.cshtml in Shared folder and write the following code to it:
@{ Exception ex = ViewData["HandleException"] as Exception; }<h1>@ex.Message</h1><div>@ex.StackTrace</div>
As you can see the Error view can grab the exception details using the HandleException key stored in the ViewData. The Message and StackTrace properties of the Exception are then outputted on the page.
If you run the application you should see the error page like this:
So far so good. Now let's add a couple of features to our [HandleException] attribute:
- The ViewName should be customizable
- There should be provision to handle only specific type of exceptions
Go ahead and add two public properties to the HandleExceptionAttribute class. These properties are shown below:
public class HandleExceptionAttribute : ExceptionFilterAttribute {public string ViewName { get; set; } = "Error";public Type ExceptionType { get; set; } = null;........ }
The ViewName property allows you to specify a custom view name that is then used while forming the ViewResult. The ExceptionType property holds the Type of the exception you wish to handle (say DivideByZeroException or FormatException).
Then modify the OnException() as shown below:
public override void OnException(ExceptionContext context) {if(this.ExceptionType != null){if(context.Exception.GetType() == this.ExceptionType){........}}else{........} }
The OnException() method now checks whether a specific ExceptionType is to be handled (non null value). If yes then it checks whether the exception being thrown matches with that type (inner if block) and accordingly ViewResult is configured. If no specific ExceptionType is to be checked then control directly goes in the else block. The code in both the cases is shown below:
var result = new ViewResult { ViewName = this.ViewName }; var modelMetadata = new EmptyModelMetadataProvider(); result.ViewData = new ViewDataDictionary (modelMetadata, context.ModelState); result.ViewData.Add("HandleException", context.Exception); context.Result = result; context.ExceptionHandled = true;
This code is quite similar to what you wrote earlier. But this time it uses the ViewName property while forming the ViewResult.
Now open the HomeController and change the [HandleException] attribute like this:
[HandleException(ViewName ="CustomError", ExceptionType =typeof(DivideByZeroException))] public IActionResult Index() {throw new Exception("This is some exception!!!");return View(); }
Now the [HandleException] attribute specifies two properties - ViewName and ExceptionType. Since ExceptionType is set to the type of DivideByZeroException the [HandleException] won't handle the error (because Index() throws a custom Exception). So, rename Error.cshtml to CustomError.cshtml and throw a DivideByZeroException. This time error gets trapped as expected.
It should be noted that [HandleException] can be applied on top of the controller class itself rather than to individual actions.
[HandleException] public class HomeController : Controller { .... .... }
More details about the ASP.NET Core filters can be found here.
That's it for now! Keep coding!!
转载于:https://www.cnblogs.com/freeliver54/p/6510720.html
[转]Create Custom Exception Filter in ASP.NET Core相关推荐
- Asp.Net Core Filter 深入浅出的那些事-AOP
一.前言 在分享ASP.NET Core Filter 使用之前,先来谈谈AOP,什么是AOP 呢? AOP全称Aspect Oriented Programming意为面向切面编程,也叫做面向方法编 ...
- 加速ASP.NET Core WEB API应用程序。 第三部分
深度重构和完善ASP.NET Core WEB API应用程序代码 (Deep refactoring and refinement of ASP.NET Core WEB API applicati ...
- 如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出
这是该系列的第一篇文章:在ASP.NET Core 3.0中使用Serilog.AspNetCore. 第1部分-使用Serilog RequestLogging来简化ASP.NET Core的日志输 ...
- 如何在ASP.NET Core中创建自定义AuthorizeAttribute?
本文翻译自:How do you create a custom AuthorizeAttribute in ASP.NET Core? I'm trying to make a custom aut ...
- vue.js crud_如何使用VS Code和ADO.NET使用ASP.NET Core执行CRUD操作
vue.js crud 介绍 (Introduction) In this article we are going to create a web application using ASP.NET ...
- 如何在 ASP.Net Core 使用 分布式缓存
ASP.Net Core 提供了多种类型的缓存,除了内存缓存和响应缓存之外,还提供了对 分布式缓存 的支持.在之前的一篇文章中,我讨论了 ASP.Net Core 的内存缓存.在本文中,我们将讨论如何 ...
- java和asp.net core,VS 2019教程:创建ASP.NET Core Web App
启动Visual Studio 2019并创建一个新项目 启动Visual Studio 2019,然后单击Create new project.选择"ASP.NET Core Web Ap ...
- VS 2019教程:创建ASP.NET Core Web App
启动Visual Studio 2019并创建一个新项目 启动Visual Studio 2019,然后单击Create new project.选择"ASP.NET Core Web Ap ...
- vs2019怎么创建html,VS 2019教程:创建ASP.NET Core Web App
启动Visual Studio 2019并创建一个新项目 启动Visual Studio 2019,然后单击Create new project.选择"ASP.NET Core Web Ap ...
最新文章
- java mp3 暂停,Java MP3播放器 - 使用jLayer播放,暂停和搜索不能正常工作
- 【CDS技术揭秘系列 02】阿里云CDS-SLS大揭秘
- Flutter浪潮下的音视频研发探索
- mysql打开sql语句日志
- 第33课 打擂台 《小学生C++趣味编程》
- mfc读取bmp文件_LIUNX 工程bmp.c 显示图片 开发板出来的图片只有一个角 求大佬解决...
- mysql模糊查询占位符python_python中的mysql数据库like模糊查询
- Java 编译,运行错误之 java.lang.UnsupportedClassVersionError: Bad version n umber in .class file
- Java--Json解析
- js constructor 和 instanceof
- UVA 1213 Sum of Different Primes
- 【C/C++】在Dosbox安装和体验Turbo C++ 3.0
- virtualbox网络配置
- codeforces AIM Tech Round 3 (Div. 2) (A~D)
- 什么是抓包 为什么要抓包
- MySQL安装 ,版本mysql-5.7.19-winx64
- Ubuntu下基于Wine环境安装Visio2007
- Storm学习(一)Storm介绍
- android 输入法全屏,android 输入法不全屏
- 第十三周 任务二