本文主要参考:http://www.asp.net/web-api/overview/error-handling/exception-handling
1、如果一个Web API控制器抛出未捕获的异常,默认情况下,大多数异常转换成HTTP响应状态码500内部服务器错误。
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; }
异常过滤器
你可以通过自定义一个异常过滤器来抓取所有用户未处理的异常。当然,不包括HttpResponseException类型的异常,它是一个特例,因为它直接返回一个http消息。
异常处理器继承自System.Web.Http.Filters.IExceptionFilter接口。新建一个异常处理器最快的方式是继承System.Web.Http.Filters.ExceptionFilterAttribute类,并重写(override)OnException方法。
web api中的异常处理器和MVC中异常处理器非常类似,尽管它们来自不同的命名空间和和函数。
下面这个例子实现了一个异常过滤器,它把NotImplementedException异常转换成http 501错误。
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); } } } }
如何来注册这些自定义的异常处理器呢?
系统提供了如下三种注册方式
1、Action上注册
public class ProductsController : ApiController { [NotImplExceptionFilter] public Contact GetContact(int id) { throw new NotImplementedException("This method is not implemented"); } }
2、控制器上注册
[NotImplExceptionFilter] public class ProductsController : ApiController { public Contact GetContact(int id) { throw new NotImplementedException("This method is not implemented"); } }
3、全局注册
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Filters.Add(new ProductStore.NotImplExceptionFilterAttribute()); // Other configuration code... } }
HttpError
HttpError对象为在http响应报文中返回错误信息提供一个一致的方法,下面是一个在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); return Request.CreateErrorResponse(HttpStatusCode.NotFound, message); } else { return Request.CreateResponse(HttpStatusCode.OK, item); } }
下面例子中演示如何通过HttpError返回模型验证错误信息
public HttpResponseMessage PostProduct(Product item) { if (!ModelState.IsValid) { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); } // Implementation not shown... }
HttpResponseException和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; } }