Asp.Net Web API 2第七課——Web API異常處理

來源:互聯網
上載者:User

標籤:

前言

閱讀本文之前,您也可以到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 FoundContent-Type: application/json; charset=utf-8Date: Thu, 09 Aug 2012 23:27:18 GMTContent-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中新增加的一個亮點機制————屬性路由,貌似很牛逼的樣子。

Asp.Net Web API 2第七課——Web API異常處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.