Contact Manager Web API 示例[4] 异常处理(Exception Handling)

联系人管理器web API是一个Asp.net web api示例程序,演示了通过ASP.NET Web API 公开联系信息,并允许您添加和删除联系人,示例地址http://code.msdn.microsoft.com/Contact-Manager-Web-API-0e8e373d

Contact Manager Web API 示例[1]CRUD 操作 已经做了一个基本的介绍,

Contact Manager Web API 示例[2] Web API Routing 介绍Web API Routing。

Contact Manager Web API 示例[3] 分页和查询(Paging and Querying)主要介绍OData的查询和分页支持。

本文主要介绍WebAPI的异常处理HttpResponseMessage。

如果 Web API 的 controller 掷出一个异常(exception),会发生什么事?默认下,最常是会把例外转译为一个 HTTP 状态代码 500 (Internal Server Error) 回应。

HttpResponseException 类 是一个特别情况。能够构建回应的信息, 这个例外能回传任何 HTTP 状态代码。例如,下面例子,如果 id 参数不存在,会回传 404 (Not Found) 状态代码。

public HttpResponseMessage<Contact> Get(int id) 
        { 
            var contact = this.repository.Get(id); 
            if (contact == null) 
            { 
 var response = new HttpResponseMessage(); 
                response.StatusCode = HttpStatusCode.NotFound; 
                response.Content = new StringContent("Contact not found"); 
                throw new HttpResponseException(response); 
            } 
            var contactResponse = new HttpResponseMessage<Contact>(contact); 
            //set it to expire in 5 minutes 
            contactResponse.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(30)); 
            return contactResponse; 
        }

异常过滤 (EXCEPTION FILTERS)

你可以通过编写 异常过滤(Exception Filter)来自己处理 Web API 的异常。当一个 controller 方法抛出任何未处理的例外,它并不是 HttpResponseException 异常,异常过滤被会执行。HttpResponseException 型别是一种特别情况,因为它是特别设计来回传 HTTP 响应。

异常过滤实现 System.Web.Http.Filters.IExceptionFilter 接口。不管如何,只需要继承 System.Web.Http.Filters.ExceptionFilterAttribute 类然后重写(override) OnException 方法。

namespace ContactManager.Filters 
{ 
    public class LogExceptionFilter : ExceptionFilterAttribute 
    { 
        public override void OnException(HttpActionExecutedContext actionExecutedContext) 
        { 
            //增加二行 Trace 代码 
            Trace.TraceError("异常: {0}", actionExecutedContext.Exception.Message); 
            Trace.TraceError("请求 URI: {0}", actionExecutedContext.Request.RequestUri); 
            base.OnException(actionExecutedContext); 
        } 
    } 
}

你也能自行控制 HTTP 响应让 Client 接收。在 HttpActionExecutedContext 参数 去修改或设置 Result 属性。我们新增一个 NotImplExceptionFilter 类别,一样继承 ExceptionFilterAttribute 类和重写 OnException 方法。

namespace ContactManager.Filters 
{ 
    public class NotImplExceptionFilter : ExceptionFilterAttribute 
    { 
        public override void OnException(HttpActionExecutedContext actionExecutedContext) 
        { 
            //增加二行 Trace 代码 
            Trace.TraceError("异常: {0}", actionExecutedContext.Exception.Message); 
            Trace.TraceError("请求 URI: {0}", actionExecutedContext.Request.RequestUri); 
            if(actionExecutedContext.Result==null) 
            { 
                actionExecutedContext.Result = new  HttpResponseMessage(); 
            } 
            //HttpStatusCode.NotImplemented = 501  
            actionExecutedContext.Result.StatusCode = HttpStatusCode.NotImplemented ; 
            actionExecutedContext.Result.Content = new StringContent("方法未执行"); 
            base.OnException(actionExecutedContext); 
        } 
    } 
}

注册异常过滤

有二种方法可以去注册异常过滤。

第一,你可以注册到全局的 GlobalConfiguration.Configuration.Filters 集合。当发生未处理的异常,异常过滤集合中会作用在所有 Web API controller action。(异常类型 HttpResponseException 也会被执行)。我们必须在 Global.asax 文件的 Application_Start 注册它。

public static void RegisterApis(HttpConfiguration config) 
{ 
   ……
    config.Filters.Add(new LogExceptionFilter());
}
protected void Application_Start() 
{ 
         RegisterApis(GlobalConfiguration.Configuration); 
}

第二,你可以注册异常过滤至指定的 action 方法,通过指定属性的方式。例如以下范例:

        [HttpGet] 
        [NotImplExceptionFilter] 
        public HttpResponseMessage<Contact> Get(int id) 
        { 
            var contact = this.repository.Get(id); 
            if (contact == null) 
            { 
                //var response = new HttpResponseMessage(); 
                //response.StatusCode = HttpStatusCode.NotFound; 
                //response.Content = new StringContent("Contact not found"); 
                //throw new HttpResponseException(response); 
                throw new NotImplementedException("此方法未执行"); 
            } 
            var contactResponse = new HttpResponseMessage<Contact>(contact); 
            //set it to expire in 5 minutes 
            contactResponse.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(30)); 
            return contactResponse; 
        }

异常过滤在 ASP.NET Web API 与 ASP.NET MVC 类似。不管如何,他们分布在不同命名空间里。特别说明,HandleErrorAttribute 类 使用在  ASP.NET MVC,无法拿来处理 Web API controller 的异常。

参考资料· System.Web.Http

· System.Net.Http

· Exception Handling in ASP.NET Web API

·ASP.NET Web API Exception Handling

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Coding迪斯尼

从0到1用java再造tcpip协议栈:实现ARP协议层

经过前两节的准备,我们完成了数据链路层,已经具备了数据包接收和发送的基础设施,本机我们在此基础上实现上层协议,我们首先从实现ARP协议开始。先简单认识一下ARP...

23130
来自专栏Android 研究

Android Handler机制11之Handler机制总结

经过上面的思考,大家是不是发现和其实我们Handler的机制基本上一致。Looper负责轮询;Message代表消息,为了区别对待,用what来做为标识符,wh...

1.3K10
来自专栏linux驱动个人学习

高通非adsp 架构下的sensor的bug调试

当休眠后,再次打开preesure sensor的时候,会出现隔一段时候后,APK才会出现数据;(数据有时候会很难出现)

14210
来自专栏码匠的流水账

聊聊hikari连接池的idleTimeout及minimumIdle属性

本文主要研究一个hikari连接池的idleTimeout及minimumIdle属性

39310
来自专栏李蔚蓬的专栏

1.Android系统源代码目录与系统目录

想要看完整个Android的源代码,需要懂C、懂脚本、懂Java、软硬兼通。所以一般情况下,我们了解源代码的框架结构,出了问题知道从哪里着手解决就可以了。这就好...

79520
来自专栏IT开发技术与工作效率

VBA按行读取csv文件与分割合并

23730
来自专栏向治洪

备忘录模式

概念 备忘录模式:又叫做快照模式,属于行为模式的一种,指在不破坏封装性的前提下,获取到一个对象的内部状态,并在对象之外记录或保存这个状态。在有需要的时候可将该对...

20880
来自专栏程序员互动联盟

【java网络】IO编程

Prequirement 在继续阅读这篇文章之前,请务必先阅读前面这篇Java IO概述,因为Java把所有的IO都统一成流(Stream)了。 TCP/IP协...

40280
来自专栏大内老A

[WCF的Binding模型]之三:信道监听器(Channel Listener)

信道管理器是信道的创建者,一般来说信道栈的中每个信道对应着一个信道管理器。基于不同的消息处理的功能,将我们需要将相应的信道按照一定的顺序能组织起来构成一个信道栈...

21050
来自专栏大内老A

WCF技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[上篇]

WCF事务编程主要涉及到这么三个方面:通过服务(操作)契约确定TransactionFlow的策略;通过事务绑定实现事务流转;通过服务操作行为控制事务的自动登记...

21980

扫码关注云+社区

领取腾讯云代金券