Asp.Net Web API 2第七课——Web API异常处理-阿里云开发者社区

开发者社区> 杰克.陈> 正文

Asp.Net Web API 2第七课——Web API异常处理

简介: 原文:Asp.Net Web API 2第七课——Web API异常处理 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.
+关注继续查看
原文: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中新增加的一个亮点机制————属性路由,貌似很牛逼的样子。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
解决.Net 4.0 A potentially dangerous Request.Form value was detected from the client 异常
解决ASP.NET 4.0   "A potentially dangerous Request.Form value was detected from the client". 错误在.net中,Request时出现有HTML或Javascript等字符串时,系统会认为是危险性值。
815 0
Web系统下Office文档的处理
在web环境中,我们经常遇到需要对Office文档进行各种各样的处理,如:格式转化、统计、修改等各种操作,如果使用Office的客户端对象模型直接处理,一般会遇到:效率低;服务器资源负载大等一系列问题,毕竟Office对象实现时主要针对的是客户端的使用而设计的,对于批量和大负载的处理自然效率欠佳。
771 0
Asp.Net Web API 2第四课——HttpClient消息处理器
原文:Asp.Net Web API 2第四课——HttpClient消息处理器 Asp.Net Web API 导航     Asp.Net Web API第一课:入门http://www.cnblogs.
711 0
asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
开发web项目时需要安装IIS,在安装好IIS的Windows7本上发布asp.net网站时,web程序已经映射到了本地IIS上,但运行如下错误提示“处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Man...
821 0
[ASP.NET]强大的网页处理类NSoup
我们如果在项目中碰到要处理HTML,如果是.NET程序员的话,强烈推荐使用NSoup,不然的话截取字符串是在是太痛苦了。NSoup是一个开源框架,是JSoup的.
1002 0
MHA 切换的2个异常(masterha_master_switch line 53)
        MHA 在测试手动故障转移和在线切换的过程中,碰到了2个比较诡异的问题,在使用IP地址调用的时候均无法测试成功,出现了Detected dead master xxx does not match with specified dead master以及xxx is not alive。
1172 0
+关注
杰克.陈
一个安静的程序猿~
10427
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载