这篇文章描述错误和异常处理在 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. 第9章 Java类的三大特性之一:继承

    1.什么是继承 子类继承父类就是对父类的扩展,继承时会自动拥有父类所拥有的处private之外的所有成员作用:增加代码复用语法格式: class 子类名 extends 父类名{…………}第9章 Ja ...

  2. winform记事本(基本功能)

    本题主要考察各种控件的应用 using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...

  3. iOS 2D绘图 (Quartz2D)之Transform(CTM,Translate,Rotate,scale)

    前言:Quartz默认采用设备无关的user space来进行绘图,当context(画板)建立之后,默认的坐标系原点以及方向也就确认了,可以通过CTM(current transformation ...

  4. CWMP开源代码研究1——开篇之作

    原创作品,转载请注明出处,严禁非法转载.如有错误,请留言! email:40879506@qq.com 声明:本系列涉及的开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅 ...

  5. mysqli_fetch_assoc php的新的库函数

    注释:mysql_fetch_assoc() 函数 定义和用法mysql_fetch_assoc() 函数从结果集中取得一行作为关联数组. 返回根据从结果集取得的行生成的关联数组,如果没有更多行,则返 ...

  6. 分布式服务框架 dubbo/dubbox 入门示例

    dubbo是一个分布式的服务架构,可直接用于生产环境作为SOA服务框架. 官网首页:http://dubbo.io/ ,官方用户指南 http://dubbo.io/User+Guide-zh.htm ...

  7. Linux(CentOs6.4)安装Git

    安装之前我们先来了解下git,并且要反问下:我为什么要使用git?svn用的不是很好嘛,我干嘛要换?... 问1:为什么需要版本控制系统? 版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订 ...

  8. 基于FPGA的飞机的小游戏

    基于FPGA的飞机的小游戏 实验原理 该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路 ...

  9. bzoj1584

    1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 467  Solved: 31 ...

  10. UI: 概述, 启动屏幕, 屏幕方向

    UI 设计概述 启动屏幕(闪屏) 屏幕方向 示例1.UI 设计概述UI/Summary.xaml <Page x:Class="Windows10.UI.Summary" x ...