Asp.Net Web API 2第七课——Web API异常处理
前言
阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html
本文主要来讲解Asp.Net Web API中错误和异常的处理,包括以下几点:
1.HttpResponseException——HTTP响应异常
2.Exception Filters——异常过滤器
3.Registering Exception Filters——注册异常过滤器
4.HttpError——HTTP错误
HttpResponseException——HTTP响应异常
如果一个Web API 控制器抛出一个未捕获的异常,会发生什么?在默认情况下,大多数异常都被转换为一个带有状态码500的内部服务器错误的HTTP响应。
这个HTTPResponseException类型是一个特殊的类型。这种异常会返回你在异常构造器中指定的任何HTTP状态码。例如,在以下方法中,如果这个id参数无效,那么会返回“404——未找到”。
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
为了对响应进行更多的控制,你也可以构造整个响应消息,并用HTTPResponseException来包含它:
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("No product with ID = {0}", id)),
ReasonPhrase = "Product ID Not Found"
}
throw new HttpResponseException(resp);
}
return item;
Exception Filters——异常过滤器
通过编写一个异常过滤器,你可以定制Web API如何处理异常。当一个控制器抛出一个未处理的异常,且这个异常不是一个HttpResponseException异常时,一个异常过滤器会被执行。HttpResponseException类型一个特殊的情况,因为它是专门设计用来返回一个HTTP响应的。
异常过滤器实现System.Web.Http.Filters.IExceptionFilter接口。编写异常过滤器最简单的方式是通过System.Web.Http.Filters.ExceptionFilterAttribute类进行派生,并重写其OnException方法。
ASP.NET Web API中的异常过滤器与Asp.Net MVC中的是极为类似的。然后,他们被声明在不同的命名空间中,且功能也是独立的。特别强调一下,Asp.Net MVC中使用的HandleErrorAttribute类不会处理Web API控制器中抛出的异常。
以下是将NotImplementedException异常转换成HTTP状态码“501 — 未实现”的一个过滤器:
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http.Filters; public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
HttpActionExecutedContext对象的Response属性含有将发送给客户端的HTTP响应消息。
Registering Exception Filters——注册异常过滤器
以下是注册Web API异常过滤器的几种方式:
- 通过动作进行注册
- 通过控制器进行注册
- 全局注册
要把过滤应用于特定的动作,在动作上添加该过滤器的注解属性:
public class ProductsController : ApiController
{
[NotImplExceptionFilter]
public Contact GetContact(int id)
{
throw new NotImplementedException("This method is not implemented");
}
}
要把过滤器运用于一个控制器的所有动作,在控制器上添加该过滤器的注解属性:
[NotImplExceptionFilter]
public class ProductsController : ApiController
{
// ...
}
要全局性地把过滤器运用于所有Web API控制器,将该过滤器的一个实例添加到GlobalConfiguration.Configuration.Filters集合。这个集合中的异常过滤器会运用于任何Web API控制器动作。
GlobalConfiguration.Configuration.Filters.Add(
new ProductStore.NotImplExceptionFilterAttribute());
如果你用的是“ASP.NET MVC 4 Web应用程序”项目模板创建的项目,要把你的Web API配置代码被放在WebApiConfig类中,它位于App_Start文件夹:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ProductStore.NotImplExceptionFilterAttribute()); // Other configuration code(其它配置代码)...
}
}
HttpError——HTTP错误
HttpError对象为在响应正文中返回错误消息提供了相应的方式。以下示例演示了如何用HttpError在响应体中返回HTTP状态码“404 — 未找到”:
public HttpResponseMessage GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var message = string.Format("Product with id = {0} not found", id);
HttpError err = new HttpError(message);
return Request.CreateResponse(HttpStatusCode.NotFound, err);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, item);
}
}
在这个例子中,如果该方法成功,它会在HTTP响应中返回产品。但如果所请求的产品未找到,则HTTP响应会在请求体中包含一个HttpError。该响应看上去大致像这样:
HTTP/1.1 Not Found
Content-Type: application/json; charset=utf-
Date: Thu, Aug :: GMT
Content-Length: {
"Message": "Product with id = 12 not found"
}
注意,在这个例子中,HttpError会被序列化成JSON。使用HttpError的一个好处是,与其它强类型模型一样,会进行同样的“content-negotiation”(暂未实现)和序列化过程。
直接替代创建HttpError对象的一种办法是,你可以使用CreateErrorResponse方法:
public HttpResponseMessage GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var message = string.Format("Product with id = {0} not found", id);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, item);
}
}
CreateErrorResponse在System.Net.Http.HttpRequestMessageExtensions类中被定义为一个扩展方法。本质上,CreateErrorResponse会创建一个HttpError实例,然后创建一个包含该HttpError的HttpResponseMessage。
Adding Custom Key-Values to HttpError把自定义的键值添加到HTTPError
HttpError类实际上是一个“键-值”集合(它派生于Dictionary<string, object>),因此你可以添加自己的“键-值”对:
public HttpResponseMessage GetProduct(int id)
{
Product item = repository.Get(id); if (item == null)
{
var message = string.Format("Product with id = {0} not found", id);
var err = new HttpError(message);
err["error_sub_code"] = ;
return Request.CreateErrorResponse(HttpStatusCode.NotFound, err);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, item);
}
}
Using HttpError with HttpResponseException以HttpResponseException的方式来使用HttpError
前面的例子是从控制器动作返回一个HttpResponseMessage消息,但你也可以使用HttpResponseException来返回一个HttpError。这让你能够在正常成功情况下返回强类型模型,而在有错误时,仍返回HttpError。
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var message = string.Format("Product with id = {0} not found", id);
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
}
else
{
return item;
}
}
总结
感觉比MVC中的异常处理更为出色,不知道新版本的MVC中的异常处理机制如何。下一篇文章将来讲解Web API2中新增加的一个亮点机制————属性路由,貌似很牛逼的样子。
Asp.Net Web API 2第七课——Web API异常处理的更多相关文章
- Asp.Net Web API 2第六课——Web API路由和动作选择
Asp.Net Web API 导航 Asp.Net Web API第一课——入门http://www.cnblogs.com/aehyok/p/3432158.html Asp.Net Web AP ...
- Asp.Net Web API 2第五课——Web API路由
Asp.Net Web API 导航 Asp.Net Web API第一课——入门 http://www.cnblogs.com/aehyok/p/3432158.html Asp.Net Web ...
- Asp.Net Web API 2第八课——Web API 2中的属性路由
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 路由就是Web API如何 ...
- 潭州课堂25班:Ph201805201 WEB 之 jQuery 第七课 (课堂笔记)
jq 的导入 <body> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js">< ...
- Kali Linux Web 渗透测试视频教程— 第七课 OpenVas
Kali Linux Web 渗透测试视频教程— 第七课 OpenVas 文/玄魂 视频教程地址:http://edu.51cto.com/course/course_id-1887.html 目录 ...
- Asp.Net Web API 2(入门)第一课
Asp.Net Web API 2(入门)第一课 前言 Http不仅仅服务于Web Pages.它也是一个创建展示服务和数据的API的强大平台.Http是简单的.灵活的.无处不在的.你能想象到几乎 ...
- List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac
List多个字段标识过滤 class Program{ public static void Main(string[] args) { List<T> list = new List& ...
- 2.4使用属性在 ASP.NET Web API 2 路由创建一个 REST API
Web API 2 支持一种新型的路由,称为属性路由.属性路由的一般概述,请参阅属性路由 Web API 2 中.在本教程中,您将使用属性路由创建一个 REST API 集合的书.API 将支持以下操 ...
- 【转载】ASP.NET MVC Web API 学习笔记---第一个Web API程序
1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过 ...
随机推荐
- Oracle客户端与服务器字符集不统一的处理
当Oracle客户端与服务器的字符集不统一时. 症状: 如:ORA-00283: ?????????? 提示信息中有好多问号. 解决方法: 1查询服务器的字符集: SQL> conn / as ...
- Eclipse/MyEclipse怎么设置个性化代码注释模板
1.打开Eclipse/MyEclipse工具,打开或创建一个Java工程,点击菜单Window->Preferences弹出首选项设置窗口 2.展开左侧Java->Code Style- ...
- Java第一天学习笔记整理
一.关键字 java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名.方法名.类名.包名. 常见的关键字: 用于定义数据类型的关键字 cla ...
- C# 接口应用及意义
写在前面:新手入行,读者勉强看看吧,写的不对的欢迎讨论,板砖轻拍! 一.定义 接口描述的是可属于任何类或结构的一组相关功能,所以实现接口的类或结构必须实现接口定义中指定的接口成员. 通常用Interf ...
- win8自动升级win8.1后 wampserver无法启动
原因是升级时win8把其他的系统服务都给停止了. 解决办法是左键点击wamp的小图标,选择apache/mysql - service - 安装服务. 然后再选择启动服务,即可.
- console.log的应用
这两天在学javascript,但是有个问题老是觉得很疑惑,那就是这两个表达式到底有啥区别,虽然结果输出都差不多,但是我想这个两个表达式被开发出来,肯定是有意义的吧!哪位高手解答下吧!Thanks i ...
- oracle中rownum和rowid的区别
rownum和rowid的区别总括: rownum和rowid都是伪列,但是两者的根本是不同的. rownum是根据sql查询出的结果给每行分配一个逻辑编号,所以你的sql不同也就会导致最终rownu ...
- openssl API网络通信
1.本文是在别人的基础上,经过测试,大体总结的.操作环境ubuntu12和ubuntu14 ****************************************************** ...
- SQL中的循环、for循环、游标
我们使用SQL语句处理数据时,可能会碰到一些需要循环遍历某个表并对其进行相应的操作(添加.修改.删除),这时我们就需要用到咱们在编程中常常用的for或foreach,但是在SQL中写循环往往显得那么吃 ...
- sublime text保存时删除行尾空格
打开sublime text,点击在Preferences, Settings-User打开的用户配置中加入以下一行: "trim_trailing_white_space_on_save& ...