这篇文章描述错误和异常处理在 ASP.NET Web API。

HttpResponseException

如果 Web API 控制器引发未捕获的异常,会发生什么?默认情况下,大多数异常被转译为 HTTP 响应状态代码 500,内部服务器错误。

HttpResponseException类型是一种特殊情况。此异常返回您在异常构造函数中指定的所有 HTTP 状态代码。例如,下面的方法返回 404,找不到,如果id参数无效。

 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;
}

异常过滤器

您可以自定义 Web API 如何处理异常通过编写的异常筛选器。当控制器方法引发任何未处理的异常时执行异常筛选器就是HttpResponseException异常。HttpResponseException型是一种特殊的情况,因为它特别针对返回的 HTTP 响应。

异常筛选器实现System.Web.Http.Filters.IExceptionFilter接口。写异常筛选器的最简单方法是从System.Web.Http.Filters.ExceptionFilterAttribute类派生和重写OnException方法。

注意:

  在 ASP.NET Web API 的异常筛选器是类似于那些在 ASP.NET MVC 中。然而,他们分别在一个单独的命名空间和函数声明。尤其是,在 MVC 中使用的HandleErrorAttribute类并不处理由 Web API 控制器引发的异常。

这里是一个过滤器,转换未实现的 HTTP 状态代码 501, NotImplementedException例外 ︰

 namespace ProductStore.Filters
{
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对象的响应属性包含将发送到客户端的 HTTP 响应消息。

注册异常过滤器

有几种方法来注册 Web API 异常筛选器 ︰

1.action

2.控制器

3.全局注册

若要将筛选器应用于具体的行动,在Action上贴上特性标签 ︰

 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 应用程序"项目模板来创建您的项目,把里面的WebApiConfig类,位于 App_Start 文件夹中的 Web API 配置代码 ︰

 public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ProductStore.NotImplExceptionFilterAttribute()); // Other configuration code...
}
}

HttpError

HttpError对象提供一致的方法来响应正文中返回错误的信息。下面的示例演示如何返回 HTTP 状态代码 404 (未找到) 与HttpError在响应正文中。

 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实例,然后创建包含HttpErrorHttpResponseMessage.

在此示例中,如果该方法是成功的它返回的 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的优点之一是它穿过任何其他强类型的模型相同的内容协商和序列化进程。

HttpError 和模型验证

对于模型验证,可以将模型状态传递给CreateErrorResponse,要在响应中包含验证错误 ︰

 public HttpResponseMessage PostProduct(Product item)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
} // Implementation not shown...
}

此示例可能会返回以下响应 ︰

 HTTP/1.1  Bad Request
Content-Type: application/json; charset=utf-
Content-Length: {
"Message": "The request is invalid.",
"ModelState": {
"item": [
"Required property 'Name' not found in JSON. Path '', line 1, position 14."
],
"item.Name": [
"The Name field is required."
],
"item.Price": [
"The field Price must be between 0 and 999."
]
}
}

关于模型验证的详细信息,请参见ASP.NET Web API 中的模型验证.

使用 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;
}
}

7.1WebApi2的异常处理的更多相关文章

  1. WebApi官方系列

    一.入门 1.1Asp.Net WebApi2 入门 1.2WebApi2的Action返回值 1.3WebApi2自动生成帮助页 二.路由 2.1WebApi2的路由规则 2.2WebApi2的Ac ...

  2. 关于.NET异常处理的思考

    年关将至,对于大部分程序员来说,马上就可以闲下来一段时间了,然而在这个闲暇的时间里,唯有争论哪门语言更好可以消磨时光,估计最近会有很多关于java与.net的博文出现,我表示要作为一个吃瓜群众,静静的 ...

  3. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  4. 异常处理汇总 ~ 修正果带着你的Net飞奔吧!

    经验库开源地址:https://github.com/dunitian/LoTDotNet 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983 ...

  5. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  6. IL异常处理

    异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法 1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像 2.EndExcep ...

  7. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  8. 【repost】JS中的异常处理方法分享

    我们在编写js过程中,难免会遇到一些代码错误问题,需要找出来,有些时候怕因为js问题导致用户体验差,这里给出一些解决方法 js容错语句,就是js出错也不提示错误(防止浏览器右下角有个黄色的三角符号,要 ...

  9. 札记:Java异常处理

    异常概述 程序在运行中总会面临一些"意外"情况,良好的代码需要对它们进行预防和处理.大致来说,这些意外情况分三类: 交互输入 用户以非预期的方式使用程序,比如非法输入,不正当的操作 ...

随机推荐

  1. 一个页面从输入URL到页面加载显示完成,这个过程都发生了什么?

    对于网址栏的URL不同的操作方式有不同的加载资源.获取数据的方式,下面的详细过程针对"在地址栏输入URL,按enter(回车)键加载资源"此种操作方式做解析,其它的方式的过程大同小 ...

  2. 第8章 文件系统管理(2)_挂载、fdisk分区及分配swap分区

    3. fdisk分区 3.1 fdisk命令分区过程 (1)添加新硬盘 (2)查看新硬盘#fdisk –l (3)使用fdisk命令分区:#fdisk /dev/sdb Fdisk交互指令说明 命令 ...

  3. hibernate缓存

    http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html http://www.cnblogs.com/xiaoluo501395377/ ...

  4. java之多线程 二

    线程的生命周期: 当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead ...

  5. VC++/MFC(VC6)开发技术精品学习资料下载汇总

    工欲善其事,必先利其器,VC开发MFC Windows程序,Visual C++或Visual Studio是必须的,恩,这里都给你总结好了,拿去吧:VC/MFC开发必备Visual C++.Visu ...

  6. Binder理解

    native takepicture -> camera -> ICamera: class bpbinder: transact -> BpBinder: transact -&g ...

  7. Error: Could not find the required version of the Java(TM) 2 Runtime Environment in'(null)'.

    今天拿到一台新机器,搭一下开发环境,安装个JDK是个很基本的事情,从Orale的网站上下了个安装,但是一直出下面的错: 我信了你的邪,Google了一圈,有人说是可能文件下载有问题,重新下载安装就可以 ...

  8. 五种方法让CSS实现垂直居中

    利用 CSS 来实现对象的垂直居中有许多不同的方法,比较难的是选择那个正确的方法.我下面说明一下我看到的好的方法和怎么来创建一个好的居中网站. 使用 CSS 实现垂直居中并不容易.有些方法在一些浏览器 ...

  9. 9个让人印象深刻的网站 JS 视觉效果

    网页设计已经提升到一个整体新的水平,Flash 渐渐失去了地位,逐渐被 HTML/JavaScript/CSS 所超越,而且一样可以实现出 Flash 复杂的特效. 本文介绍 8 个让人印象深刻的网站 ...

  10. ZH奶酪:自然语言处理工具LTP语言云调用方法

    前言 LTP语言云平台 不支持离线调用: 支持分词.词性标注.命名实体识别.依存句法分析.语义角色标注: 不支持自定义词表,但是你可以先用其他支持自定义分词的工具(例如中科院的NLPIR)把文本进行分 ...