并非所有的异常都需要 try-catch 进行重复的处理,这会导致大量的重复性代码,一旦后续系统出现异常处理机制的修改,随着代码量增多,修改也会变的更加困难。

ASP.NET Web API 中特别增加了全局异常过滤器功能,诸如于此的还有很多过滤器可供开发者选择,以实现面向切面编程,它们在取代重复性编码这一目标的路上,作出很多贡献,同时降低了后期维护代码的难度,提升了可读性。

大多数异常处理的 try-catch 都通常是同样的写法(记录异常日志、返回错误信息等),因此我们可以将他们统一写在一个过滤器中,让 API 在出现异常时,即使没有使用 try-catch 嵌套异常位置和解决方案,也能够自动进入期望的异常处理方法。


注意:这是专门针对 Web API 所使用的全局异常处理器。如果是 Controller,则它有另外一套全局异常处理机制,因为通常情况下 MVC 的控制器不只返回Json字符串,通常要涉及页面View,文件File,Json字符串等。

Get Start

下面我们以一个最简单的异常处理过滤器代码为例,来说明应当如何使全局异常处理器生效:

1.创建一个类 MyExceptionFilterAttribute,继承 ExceptionFilterAttribute, System.Web.Mvc.IExceptionFilter 并实现接口方法

using Newtonsoft.Json;

using System.Net.Http;

using System.Web.Http.Filters;

using System.Web.Mvc;

namespace WebAPITest.Filters

{
     public class MyExceptionFilterAttribute : ExceptionFilterAttribute, System.Web.Mvc.IExceptionFilter
     {
         //MVC过滤器要求必须继承此接口才允许注册,但我们可以继承、实现但不写它。
         public void OnException(ExceptionContext filterContext)
         {
             throw new NotImplementedException();
         }

//真正能让API全局异常过滤器在出现异常时生效的是这个家伙:
         public override void OnException(HttpActionExecutedContext actionExecutedContext)
         {
             base.OnException(actionExecutedContext);

actionExecutedContext.Response = new HttpResponseMessage() { Content = new StringContent("出现异常") };
             return;

}

}

2.为此全局异常处理器进行注册:

打开文件夹 App_Start 下的 FilterConfig.cs 为过滤器注册,由此才能使得过滤器生效。

特别说明:一旦进行了全局注册,则所有方法出现异常时,过滤器都会生效。

public static void RegisterGlobalFilters(GlobalFilterCollection filters)

{
     filters.Add(new MyExceptionFilterAttribute());

}


作为特性标签使用

当然,上述 MyExceptionFilterAttribute 除了可注册为全局异常过滤器以外,也可以单独为 API 中的某些方法使用:(注意,方法本身就是"try",过滤器是"catch"。所以不再需要在方法体内再次 try-catch)

using System.Net.Http;

using System.Web.Http;

using WebAPITest.Filters;

using WebAPITest.Models;

namespace WebAPITest.Controllers

{
     //你也可以把过滤器标签打在这个地方,这代表该API类下的所有接口均接受[MyExceptionFilter]接管异常处理。
     public class TestController : ApiController
     {
         [MyExceptionFilter]     //特性标签打在此处,则 UserException 方法出现异常时会触发 MyExceptionFilterAttribute 中的异常处理方法。
         public HttpResponseMessage UserException()
         {
             throw new UserException("用户异常");
         }

[MyExceptionFilter]     //同上,这一特性标签将帮助 SystemException 方法处理异常。
         public HttpResponseMessage SystemException()
         {
             throw new Exception();
         }

}

}

标签与全局注册的优先级问题

多个特性标签,可以全局注册,可以单独在方法名称上、类名上混合使用,那么如果一个标签被全局注册,另一个标签被单独打在方法名上或者类名上,则最终哪一个处理器的方法会被触发?

这些家伙的优先级其实和 css 层叠样式表的优先级相仿。

即:如果我们全局注册过一个过滤器A,又在 ApiController 类的最顶端打了另外一个B、又在Action方法上打了第三个异常处理器C,那么默认只会执行最靠近 Action 的C处理器,也就是说:ActionFilter > ClassFilter > GlobalFilter。

另外如果需要多次执行全部生效,即:全局一次,Controller类一次,Action一次,那么则需要为过滤器顶端加那么一个标签 [AttributeUsage(AttributeTargets.All,AllowMultiple = true)],然后当异常触发时,他们就能够支持多次执行。

当然,真正的异常处理还会涉及很多复杂的内容,这只是一个概览。例如返回值需要被标准化(包含状态码、消息、响应流等内容),调用异常处理工具向服务器发送异常信息记录,记录请求参数,对GET/POST请求导致异常的差异化处理方法等。

但我们在这里提供的是一个思路,让你知道,精简代码、提升开发效率其实可以有更多的方法和可能性。而不必非要使用同一种方式,当你觉得某些步骤一直在不断重复,则应当已经有早期的开发者给出了解决方案,而你需要去发现他们。

在 ASP.NET Web API 中使用 Attribute 统一处理异常的更多相关文章

  1. 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化

    谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...

  2. ASP.NET Web API中的参数绑定总结

    ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...

  3. 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

    原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  4. 【ASP.NET Web API教程】4.1 ASP.NET Web API中的路由

    原文:[ASP.NET Web API教程]4.1 ASP.NET Web API中的路由 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. ...

  5. 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理

    在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...

  6. ASP.NET Web API中的Controller

    虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...

  7. 在ASP.NET Web API中使用OData

    http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...

  8. ASP.NET Web API 中的异常处理(转载)

    转载地址:ASP.NET Web API 中的异常处理

  9. Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...

随机推荐

  1. Matlab Tricks(二十三)—— 保存图像到 pdf

    printme = @(txt) print('-dpdf', sprintf('figures/Example_%s',txt)); % 该匿名函数的接受的参数为字符串类型,也即欲保存的文件名: % ...

  2. Android经典项目开发之天气APP实例分享

    原文:Android经典项目开发之天气APP实例分享 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/mzc186/article/details/5 ...

  3. MyBatis 模板

    mybatis-config.xml: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE co ...

  4. 图像滤镜艺术---流行艺术风滤镜特效PS实现

    原文:图像滤镜艺术---流行艺术风滤镜特效PS实现 今天,本人给大家介绍一款新滤镜:流行艺术风效果,先看下效果吧! 原图 流行艺术风效果图 上面的这款滤镜效果是不是很赞,呵呵,按照本人以往的逻辑,我会 ...

  5. centos 6.5 搭建ftp 服务器(vsftpd的配置文件说明)

    0x00 如何快速的搭建简易的资源发布站 开启简易的python http服务器 1 2 cd /home/your_path python -m SimpleHTTPServer 8000 开启防火 ...

  6. Windows Phone锁屏背景相关代码

    LockScreenManager: 启用应用程序,查看该应用程序是否是当前锁定屏幕背景提供程序,并将自己设置为提供程序. 属性: IsProvidedByCurrentApplication 只读指 ...

  7. Redis简介和安装

    Redis介绍 Redis是一种Key-Value存储系统(数据库),其提供了一组丰富的数据结构,如List,Sets,Hashes和Ordered Sets Redis安装 wget <Red ...

  8. nginx 配置https并自签名证书

    2016-10-28 转载请注明出处:http://daodaoliang.com/ 作者: daodaoliang 版本: V1.0.1 邮箱: daodaoliang@yeah.net 参考链接: ...

  9. 海康威视频监控设备Web查看系统(三):Web篇

    声明:本系列文章只提供交流与学习使用.文章中所有涉及到海康威视设备的SDK均可在海康威视官方网站下载得到.文章中所有除官方SDK以为的代码均可随意使用,任何涉及到海康威视公司利益的非正常使用由使用者自 ...

  10. 基于ASP.NET的新闻管理系统(一)

    1. 项目简介 1.1设计内容 (1)可以在首页查看各类新闻,可以点击新闻查看具体内容:可以查看不同类型的新闻,并了解热点新闻,可以在搜索框里输入要查找的内容. (2)在后台界面中,管理员可以修改密码 ...