[转]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!!
[转]Create Custom Exception Filter in ASP.NET Core的更多相关文章
- java中如何创建自定义异常Create Custom Exception
9.创建自定义异常 Create Custom Exception 马克-to-win:我们可以创建自己的异常:checked或unchecked异常都可以, 规则如前面我们所介绍,反正如果是chec ...
- 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】
Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...
- 004.Create a web app with ASP.NET Core MVC using Visual Studio on Windows --【在 windows上用VS创建mvc web app】
Create a web app with ASP.NET Core MVC using Visual Studio on Windows 在 windows上用VS创建mvc web app 201 ...
- Global exception handling in asp.net core webapi
在.NET Core中MVC和WebAPI已经组合在一起,都继承了Controller,但是在处理错误时,就很不一样,MVC返回错误页面给浏览器,WebAPI返回Json或XML,而不是HTML.Us ...
- Custom Exception in ASP.NET Web API 2 with Custom HttpResponse Message
A benefit of using ASP.NET Web API is that it can be consumed by any client with the capability of m ...
- [转]How do you create a custom AuthorizeAttribute in ASP.NET Core?
问: I'm trying to make a custom authorization attribute in ASP.NET Core. In previous versions it was ...
- [转]ASP.NET Core Exception Filters and Resource Filters
本文转自:https://damienbod.com/2015/09/30/asp-net-5-exception-filters-and-resource-filters/ This article ...
- Asp.Net Core Filter 深入浅出的那些事-AOP
一.前言 在分享ASP.NET Core Filter 使用之前,先来谈谈AOP,什么是AOP 呢? AOP全称Aspect Oriented Programming意为面向切面编程,也叫做面向方法编 ...
- Filters in ASP.NET Core
Filters in ASP.NET Core allow code to be run before or after specific stages in the request processi ...
随机推荐
- loj #2116. 「HNOI2015」开店
#2116. 「HNOI2015」开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的想法当然非 ...
- 【SSO单点系列】(5):CAS4.0 单点流程序列图
刚过元旦假期,感觉自己好久没写博客了,今天更新一篇,主要是CAS 的一个流程图. ps: 这两张图 是直接从官网上找的,都是简单的英语,我这种英语四级没过都看得懂,大家应该没有压力. 1.CAS 基本 ...
- mysql主从复制数据库
mysql主从复制相信已经用得很多了,但是由于工作原因一直没怎么用过.趁着这段时间相对空闲,也就自己实现一遍.尽管互联网上已有大把类似的文章,但是自身实现的仍然值得记录. 环境: 主服务器:cento ...
- YY的GCD 数学
题目描述 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 kAc这种傻×必然不会了,于 ...
- 【Java】qatools.properties
Link: https://github.com/qatools/properties 今天在GitHub上看到一个Java库,能方便帮助读取properties的配置文件. 具体使用可以参考上面的链 ...
- 开发环境,eclipse编辑器java代码自动提示
Eclipse+ADT+Android SDK 搭建安卓开发环境 eclipse编辑器java代码自动提示 window-->Preferences-->JAva-->Content ...
- Android 应用资源及R文件的位置
1.介绍 (1)常识 (2)在res目录下新建资源文件(例如数字资源) app--->res,选择res,右击new--->value resource file 2.字符资源(strin ...
- json语法和使用
一.JSON 概述: JavaScript Object Natation,是一种轻量级的数据交换技术规范. 二.使用流程: 在服务端将java对象转换为JSON,然后发送到浏览器,在浏览器上在讲JS ...
- loj 2038 / 洛谷 P4345 [SHOI2015] 超能粒子炮・改 题解
好玩的推式子 题目描述 曾经发明了脑洞治疗仪与超能粒子炮的发明家 SHTSC 又公开了他的新发明:超能粒子炮・改--一种可以发射威力更加强大的粒子流的神秘装置. 超能粒子炮・改相比超能粒子炮,在威力上 ...
- webstorm识别 ftl文件
webstorm对freemaker语法是原生支持的,也不需要安装什么插件,你可以直接在webstorm新建个File Types即可 file->settings->file types ...