HttpResponseException HTTP響應異常 如果Web API控制器拋出一個未捕捉的異常,會發生什麼呢?在預設情況下,大多數異常都會轉換為一個帶有狀態碼500的內部伺服器錯誤的HTTP響應。 這個HTTPResponseException類型是一個特殊的類型。這種異常會返回你在異常 ...
HttpResponseException-----HTTP響應異常
如果Web API控制器拋出一個未捕捉的異常,會發生什麼呢?在預設情況下,大多數異常都會轉換為一個帶有狀態碼500的內部伺服器錯誤的HTTP響應。
這個HTTPResponseException類型是一個特殊的類型。這種異常會返回你在異常構造器中指定的任何HTTP狀態碼。例如,在以下方法中,如果這個id參數無效,那麼會返回“404---未找到”
1 public Product GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item == null) 5 //未找到返回一個404的狀態碼 6 throw new HttpResponseException(HttpStatusCode.NotFound); 7 return item; 8 }
為了響應進行更多的控制,你也可以構造整個響應消息,並用HTTPResponseMessage來包含它:
1 public Product GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item == null) 5 //未找到返回一個404的狀態碼 6 { 7 var resp = new HttpResponseMessage(HttpStatusCode.NotFound) 8 { 9 Content = new StringContent(String.Format("No product with ID={0}", id)), 10 ReasonPhrase = "Product ID Not Found" 11 }; 12 throw new HttpResponseException(resp); 13 } 14 return item; 15 }
Exception Filters---異常過濾器
通過編寫一個異常過濾器,你可以定製Web API如何處理異常。當一個控制器拋出一個未處理異常,且這個異常不是一個HttpResponseException異常時,一個異常過濾器會被執行。HttpResponseException類型是一個特殊情況,因為它是專門設計用來返回一個HTTP響應的。
異常過濾器實現System.Web.Http.Filters.IExceptionFilter介面。編寫異常過濾器最簡單的方法是通過System.Web.Fitlers.ExceptionFilterAttribute類進行派生,並重寫OnException方法。
註意:ASP.NET Web API中的異常過濾器與ASP.NET MVC中是及其相似的。然後,它們被聲明在不用的命名空間下,且功能也是獨立的。特別強調以下,ASP.NET MVC中使用的HandlerErrorFilterAttribute不會處理Web API控制器拋出的異常。
以下是將NotImplementedException異常轉換成HTTP狀態碼“501 - 未實現”的過濾器:
1 namespace WebAPIDemo.Filter 2 { 3 public class NotImpleExceptionFilterAttribute:ExceptionFilterAttribute 4 { 5 public override void OnException(HttpActionExecutedContext actionExecutedContext) 6 { 7 if (actionExecutedContext.Exception is NotImplementedException) 8 actionExecutedContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.NotImplemented); 9 } 10 } 11 }
HttpActionExecutedContext對象的Response屬性含有發送到客戶端的HTTP響應消息
Registering Exception Filters --- 註冊異常過濾器
以下是註冊Web API異常過濾器的幾種方式
1.通過Action註冊
2.通過Controller註冊
3.通過全局註冊
要把過濾器應用特定的Action,在Action中添加過濾器的註解屬性
1 [NotImpleExceptionFilter] 2 public Product GetProduct(int id) 3 { 4 var item = repository.Get(id); 5 if (item == null) 6 //未找到返回一個404的狀態碼 7 { 8 var resp = new HttpResponseMessage(HttpStatusCode.NotFound) 9 { 10 Content = new StringContent(String.Format("No product with ID={0}", id)), 11 ReasonPhrase = "Product ID Not Found" 12 }; 13 throw new HttpResponseException(resp); 14 } 15 return item; 16 }
要把過濾器應用於一個控制器的所有Action,可以在Controller上添加過濾器的註解屬性
[NotImpleExceptionFilter] public class ProductController : ApiController {
}
要全局性的把過濾器運用於所有的Web API控制器將該過濾器的一個實例添加GlobalConfiguration.Configuration.Filter集合。這個集合中的所有異常過濾器會應用於任何Web API控制器Action
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { //註冊全局異常過濾器 GlobalConfiguration.Configuration.Filters.Add(new NotImpleExceptionFilterAttribute()); } }
HttpError----HTTP錯誤
HttpError對象為在響應正文中返回錯誤消息提供了響應的方法。以下實例演示瞭如何用HttpError在響應中返回HTTP狀態碼“404--未找到”:
1 public HttpResponseMessage GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item != null) 5 return Request.CreateResponse(HttpStatusCode.OK, item); 6 var message = string.Format("Product with id = {0} not found", id); 7 HttpError httpError = new HttpError(message); 8 return Request.CreateResponse(HttpStatusCode.NotFound, httpError); 9 }
在這個例子中,如果該方法成功,它會在HTTP響應中返回產品。但如果所請求的產品未找到,則HTTP響應會在請求體中包含一個HttpError。該響應看起來大致像這樣
1 HTTP/1.1 404 Not Found 2 Content-Type: application/json; charset=utf-8 3 Date: Thu, 09 Aug 2012 23:27:18 GMT 4 Content-Length: 51 5 6 { 7 "Message": "Product with id = 12 not found" 8 }
註意。在這個例子中,HttpError會被序列化成JSON。使用HttpError的一個好處是,與其它強類型模型一樣,會進行同樣的“content-negotiation”(暫未實現)和序列過程
直接替代創建HttpError對象的一種方法是:你可以使用CreateErrorResponse方法:
1 public HttpResponseMessage GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item != null) 5 return Request.CreateResponse(HttpStatusCode.OK, item); 6 var message = string.Format("Product with id = {0} not found", id); 7 return Request.CreateErrorResponse(HttpStatusCode.NotFound, message); 8 }
CreateErrorResponse在System.Net.Http.HttpRequsetMessageExtensions類中被定義的一個擴展方法。本質上,CreateErrorResponse會創建一個HttpError實例,然後創建一個包含該HttpError的HttpResponseMessage
Adding Custom Key-Values to HttpError 把自定義的鍵值添加到HttpError
HttpError類實際上是個鍵--值集合,(派生與於Dictionary<String,Object>),因此你可以添加自己的鍵--值對
1 public HttpResponseMessage GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item != null) 5 return Request.CreateResponse(HttpStatusCode.OK, item); 6 var message = string.Format("Product with id = {0} not found", id); 7 var err = new HttpError(message); 8 err["error_sub_code"] = 42; 9 return Request.CreateErrorResponse(HttpStatusCode.NotFound, err); 10 }
Using HttpError with HttpResponseException以HttpResponseException的方式來使用HttpError
前面的例子是從Action返回一個HttpResponseMessage消息,但你也可以使用HttpResponseException來返回一個HttpError。這讓你能夠在正常成功情況下返回強類型模型,而在錯誤時,仍返回HttpError
1 public Product GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item != null) 5 return item; 6 var message = string.Format("Product with id = {0} not found", id); 7 throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, message)); 8 }