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异常过滤器的几种方式:

  1. 通过动作进行注册
  2. 通过控制器进行注册
  3. 全局注册

要把过滤应用于特定的动作,在动作上添加该过滤器的注解属性:

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 404 Not Found
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Aug 2012 23:27:18 GMT
Content-Length: 51

{
  "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);
    }
}

CreateErrorResponseSystem.Net.Http.HttpRequestMessageExtensions类中被定义为一个扩展方法。本质上,CreateErrorResponse会创建一个HttpError实例,然后创建一个包含该HttpErrorHttpResponseMessage

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"] = 42;
        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中新增加的一个亮点机制————属性路由,貌似很牛逼的样子。

时间: 2024-12-10 22:53:39

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 API第二课——CRUD操作http://www.cnblogs.com/aehyok/p/3434578.html Asp.Net Web API第三课——.NET客户端调用Web API http://www.cnblogs.com/aehyok/p/3439698.html Asp.Net Web

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 API第二课——CRUD操作 http://www.cnblogs.com/aehyok/p/3434578.html Asp.Net Web API第三课——.NET客户端调用Web API http://www.cnblogs.com/aehyok/p/3439698.html Asp.Net

Asp.Net Web API 2第八课——Web API 2中的属性路由

参考页面: http://www.yuanjiaocheng.net/webapi/web-api-gaisu.html http://www.yuanjiaocheng.net/webapi/create-web-api-proj.html http://www.yuanjiaocheng.net/webapi/test-webapi.html http://www.yuanjiaocheng.net/webapi/web-api-controller.html http://www.yuan

Web前端学习-第七课HTML篇

Q15:HTML5有哪些API?结合文字和代码说明主要API.(P683) requestAnimationFrame(): 早期动画循环(setInterval()): mozRequstAnimation:告诉浏览器某些JavaScript代码将要执行动画.接受一个参数,即在重回屏幕前调用的一个函数,负责改变下一次重绘时的DOM样式. webkitRequestAnimationFrame与meRequestAnimationFrame Page Visibility API Documen

VB API 之 第七课 字体应用四

SelectClipRgn 功能:选取一个区域新的剪切区域 Declare Function SelectClipRgn Lib "gdi32" Alias "SelectClipRgn" (ByVal hdc As Long, ByVal hRgn As Long) As Long 参数 hdc:设备环境句柄. hrgn:标识被选择的区域. 返回值:返回一个剪辑区域复杂度,可以是下列值之一. NULLREGION:区域为空: SIMPLEREGION:区域为单个矩

Kali Linux Web 渗透测试视频教程— 第七课 OpenVas

Kali Linux Web 渗透测试视频教程— 第七课 OpenVas 文/玄魂 视频教程地址:http://edu.51cto.com/course/course_id-1887.html 目录 Kali Linux Web 渗透测试— 第七课 OpenVas................................................... 1 Openvas简介.......................................................

Asp.Net Web API 2第十课——使用OWIN自承载Web API

前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本教程主要来展示在控制台应用程序中如何通过OWIN来承载Web API. Open Web Interface for .NET (OWIN)在Web服务器和Web应用程序之间建立一个抽象层.OWIN将网页应用程序从网页服务器分离出来,然后将应用程序托管于OWIN的程序而离开IIS之外. 本文仍将使用VS2013. 本文的示

ASP.NET MVC Web API 学习笔记---第一个Web API程序

http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html 1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过在浏览器中使用 JavaScript来创建更丰富的HTML体验.所以我相信Web API会越来越有它的用武之地. 说道Web API很多人都会想到Web服务,但是他们仍然有

【ASP.NET Web API2框架揭秘】 初识Web API

Web Api 是什么? MSDN:ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动设备)的 HTTP 服务 百度百科:Web API是网络应用程序接口. 个人理解:Web API 是提供给多种客户端对data做CRUD(增删查改)操作的统一接口 ------------------------------------------- Asp.net Web API 支持多种寄宿方式 1,IIS作为宿主(创建一个Asp.net web应用程序作为Web