原文:http://www.asp.net/web-api/overview/error-handling/exception-handling

This article describes error and exception handling in ASP.NET Web API.

HttpResponseException

What happens if a Web API controller throws an uncaught exception? By default, most exceptions are translated into an HTTP response with status code 500, Internal Server Error.

The HttpResponseException type is a special case. This exception returns any HTTP status code that you specify in the exception constructor. For example, the following method returns 404, Not Found, if the id parameter is not valid.

public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}

For more control over the response, you can also construct the entire response message and include it with the 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

You can customize how Web API handles exceptions by writing an exception filter. An exception filter is executed when a controller method throws any unhandled exception that is not an HttpResponseException exception. The HttpResponseException type is a special case, because it is designed specifically for returning an HTTP response.

Exception filters implement the System.Web.Http.Filters.IExceptionFilter interface. The simplest way to write an exception filter is to derive from the System.Web.Http.Filters.ExceptionFilterAttribute class and override the OnException method.

Exception filters in ASP.NET Web API are similar to those in ASP.NET MVC. However, they are declared in a separate namespace and function separately. In particular, the HandleErrorAttribute class used in MVC does not handle exceptions thrown by Web API controllers.

Here is a filter that converts NotImplementedException exceptions into HTTP status code 501, Not Implemented:

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

The Response property of the HttpActionExecutedContext object contains the HTTP response message that will be sent to the client.

Registering Exception Filters

There are several ways to register a Web API exception filter:

  • By action
  • By controller
  • Globally

To apply the filter to a specific action, add the filter as an attribute to the action:

public class ProductsController : ApiController
{
[NotImplExceptionFilter]
public Contact GetContact(int id)
{
throw new NotImplementedException("This method is not implemented");
}
}

To apply the filter to all of the actions on a controller, add the filter as an attribute to the controller class:

[NotImplExceptionFilter]
public class ProductsController : ApiController
{
// ...
}

To apply the filter globally to all Web API controllers, add an instance of the filter to the GlobalConfiguration.Configuration.Filterscollection. Exeption filters in this collection apply to any Web API controller action.

GlobalConfiguration.Configuration.Filters.Add(
new ProductStore.NotImplExceptionFilterAttribute());

If you use the "ASP.NET MVC 4 Web Application" project template to create your project, put your Web API configuration code inside theWebApiConfig class, which is located in the App_Start folder:

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ProductStore.NotImplExceptionFilterAttribute()); // Other configuration code...
}
}

HttpError

The HttpError object provides a consistent way to return error information in the response body. The following example shows how to return HTTP status code 404 (Not Found) with an HttpError in the response body.

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 is an extension method defined in the System.Net.Http.HttpRequestMessageExtensions class. Internally,CreateErrorResponse creates an HttpError instance and then creates an HttpResponseMessage that contains the HttpError.

In this example, if the method is successful, it returns the product in the HTTP response. But if the requested product is not found, the HTTP response contains an HttpError in the request body. The response might look like the following:

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"
}

Notice that the HttpError was serialized to JSON in this example. One advantage of using HttpError is that it goes through the samecontent-negotiation and serialization process as any other strongly-typed model.

HttpError and Model Validation

For model validation, you can pass the model state to CreateErrorResponse, to include the validation errors in the response:

public HttpResponseMessage PostProduct(Product item)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
} // Implementation not shown...
}

This example might return the following response:

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 320 {
"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."
]
}
}

For more information about model validation, see Model Validation in ASP.NET Web API.

Using HttpError with HttpResponseException

The previous examples return an HttpResponseMessage message from the controller action, but you can also use HttpResponseExceptionto return an HttpError. This lets you return a strongly-typed model in the normal success case, while still returning HttpError if there is an error:

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;
}
}

Exception Handling in ASP.NET Web API webapi异常处理的更多相关文章

  1. Exception Handling in ASP.NET Web API

    public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErr ...

  2. Global Error Handling in ASP.NET Web API 2(webapi2 中的全局异常处理)

    目前,在Web API中没有简单的方法来记录或处理全局异常(webapi1中).一些未处理的异常可以通过exception filters进行处理,但是有许多情况exception filters无法 ...

  3. ASP.NET Web API之消息[拦截]处理

    标题相当难取,内容也许和您想的不一样,而且网上已经有很多这方面的资料了,我不过是在实践过程中作下记录.废话少说,直接开始. Exception 当服务端抛出未处理异常时,most exceptions ...

  4. 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

    原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  5. ASP.NET Web API 2中的错误处理

    前几天在webapi项目中遇到一个问题:Controller构造函数中抛出异常时全局过滤器捕获不到,于是网搜一把写下这篇博客作为总结. HttpResponseException 通常在WebAPI的 ...

  6. ASP.NET Web API之消息[拦截]处理(转)

    出处:http://www.cnblogs.com/Leo_wl/p/3238719.html 标题相当难取,内容也许和您想的不一样,而且网上已经有很多这方面的资料了,我不过是在实践过程中作下记录.废 ...

  7. ASP.NET Web API系列教程目录

    ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...

  8. ASP.NET Web API系列教程(目录)(转)

    注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内 ...

  9. [转]ASP.NET Web API系列教程(目录)

    本文转自:http://www.cnblogs.com/r01cn/archive/2012/11/11/2765432.html 注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP ...

随机推荐

  1. 概率 light oj 1248

    t组样例 n<100010 dp[i]  从i翻到n面的期望 接下来翻 可能是i面已经有的 也可能是n-i面没有的 dp[i]=i/n*(dp[i]+1)+(n-i)/n*(dp[i+1]+1) ...

  2. 02python算法-二分法简介

    老规矩: 什么是二分法: 其实是一个数学领域的词,但是在计算机领域也有广泛的使用. 为什么需要二分法? 当穷举算法性能让你崩溃时. 二分法怎么用呢? 让我们先玩一个游戏先,我心里想一个100以内的整数 ...

  3. 如何知道某个网站的IP地址

    命令行窗口得到ip地址 1按键盘上的win键(alt键左面的小窗口)+R键 调用运行 2输入cmd 确定 调用系统的 命令行窗口 3在命令行窗口里输入 ping + 空格键 + www.*****.c ...

  4. awk打印出当前行的上一行

    #awk '/B/{print a;}{a=$0}' a.txt A # cat a.txt A BCDE

  5. 【Codeforces 723C】Polycarp at the Radio 贪心

    n个数,用最少的次数来改变数字,使得1到m出现的次数的最小值最大.输出最小值和改变次数以及改变后的数组. 最小值最大一定是n/m,然后把可以改变的位置上的数变为需要的数. http://codefor ...

  6. 【HDU 5858】Hard problem

    边长是L的正方形,然后两个半径为L的圆弧和中间半径为L的圆相交.求阴影部分面积. 以中间圆心为原点,对角线为xy轴建立直角坐标系. 然后可以联立方程解出交点. 交点是$(\frac{\sqrt{7} ...

  7. 使用navicat连接mysql要报10038的错误

    1.mysql的设置 (1)授权mysql>grant all privileges on *.*  to  'root'@'%'  identified by 'youpassword'  w ...

  8. bzoj4305: 数列的GCD

    要求k个与原序列中的数不同,就是要求(n-k)个相同,令K=n-k 然后cnt[i]表示序列a中i的倍数的个数 f[i]表示gcd为i的倍数的方案数 f[i]=C(cnt[i],K)*(m/i-1)^ ...

  9. 73.Android之SparseArray替代HashMap

    转载:https://liuzhichao.com/p/832.html HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果.最近在做一个Android项目,在代码中定 ...

  10. Leetcode Perfect Square

    这道题首先想到的算法是DP.每个perfect square number对应的解都是1.先生成一个n+1长的DP list.对于每个i,可以用dp[i] = min(dp[j] + dp[i-j], ...