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
· Exception Handling in ASP.NET Web API
·ASP.NET Web API Exception Handling
- Linux 系统与数据库安全
- 运维必备技能 WEB 日志分析
- Elasticsearch 一键安装含中文分词
- Session 的 Cookie 域处理(多域名虚拟主机)
- ElasticSearch + Logstash + Kibana 日志采集
- ElasticSearch + Logstash + Kibana 一键安装
- Oracle 表空间管理
- 数据加密字段加密
- 《Netkiller Virtualization 手札》Docker 卷管理
- PHP高级编程之守护进程
- Spring boot with Docker
- Spring boot with Service
- Spring boot with PostgreSQL
- Struts2 S2-046, S2-045 Firewall(漏洞防火墙)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 输入示例,自动生成代码:TensorFlow官方工具TF-Coder已开源
- 聊聊java8中的@sun.misc.Contended与伪共享
- InnoDB Tidbit:The doublewrite buffer wastes 32 pages (512 KiB) (12.双写缓冲区会导致512KB的浪费)
- 10 | Tornado源码分析:Gen 对象(上)
- springboot使用spring-cloud-starter-alibaba-sentinel导致响应变成xml格式
- 内网安全攻防之内网渗透测试基础
- CMake脚本中如何修改XCode工程属性?
- 数值微分|有限差分法的误差分析
- Odyssey
- 【MySQL】之join算法详解
- 性能最佳实践:查询模式和分析
- Node 如何在 Controller 层进行数据校验
- FlutterDojo设计之道——状态管理之路(二)
- EyouCms前台GetShell漏洞复现
- CentOS7系统使用rpm方式安装MySQL5.7