[翻译] ASP.NET WebAPI 中的异常处理
原文链接:https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling
本文介绍了在 ASP.NET Web API 中的错误和异常处理
- HttpResponseException
- Exception Filters
- Registering Exception Filters
- HttpError
HttpResponseMessage
如果一个 Web API 控制器抛出一个未处理的异常会发生什么?默认情况,大多数异常会被转换为 HTTP 响应,状态码为500(服务器内部错误)。
HttpResponseMessage 类型是一种特殊情况。该异常返回异常构造函数中指定的任何 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;
}
异常过滤器
你可以通过写一个 异常过滤器 来自定义 Web API 如何处理异常。 当一个控制器抛出一个未处理异常时,异常过滤器就会执行 ---- 而这并不是一个 HttpResponseException 异常。 HttpResponseException 类型是一种特殊情况,因为它专门用于返回 HTTP 响应。
ASP.NET Web API 中的异常过滤器和 ASP.NET MVC 中的异常过滤器很相似。但是,但是,它们分别声明在单独的命名空间和函数中。特别地,MVC中使用的HandleErrorAttribute 类不处理 Web API 控制器抛出的异常。
这里有一个过滤器,将**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);
}
}
}
}
**HttpActionExecutedContext ** 对象的 **Response **属性包含将被发送给客户端的响应消息。
注册异常过滤器
有集中方法注册 Web API 异常过滤器:
- 通过 Action
- 通过 Controller
- 全局
为指定的 Action 应用过滤器:
public class ProductsController : ApiController
{
[NotImplExceptionFilter]
public Contact GetContact(int id)
{
throw new NotImplementedException("This method is not implemented");
}
}
为 Controller 的所有 Action应用过滤器:
[NotImplExceptionFilter]
public class ProductsController : ApiController
{
// ...
}
为全局所有的 Web API Controller 应用过滤器,要在 GlobalConfiguration.Configuration.Filters 集合中添加一个过滤器实例。 在这个集合中的异常过滤器应用到任何 Web API Controller 的 Action:
GlobalConfiguration.Configuration.Filters.Add(
new ProductStore.NotImplExceptionFilterAttribute());
如果你是用 "ASP.NET MVC 4 Web Application" 项目模版创建的项目,把 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
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);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, item);
}
}
CreateErrorResponse 是 System.Net.Http.HttpRequestMessageExtensions 类的一个扩展方法,在内部 CreateErrorResponse 构建一个 HttpError 实例,然后创建一个包含 HttpError 的 **HttpResponseMessage **。
在下面例子中,如果方法成功将在 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 的一个优点是,它经历了与任何其他强类型模型相同的内容协商和序列化过程。
HttpError and Model Validation
对模型验证来说,你可以把模型状态传给 CreateErrorResponse ,将会在响应中包含验证错误消息:
public HttpResponseMessage PostProduct(Product item)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
// Implementation not shown...
}
这个示例可能返回以下响应:
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."
]
}
}
更多关于模型绑定的信息,请参见Model Validation in ASP.NET Web API。
和 HttpResponseException 一起使用 HttpError
前面的示例,从控制器的 Action 返回一个 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;
}
}
[翻译] ASP.NET WebAPI 中的异常处理的更多相关文章
- 关于ASP.NET WebAPI中HTTP模型的相关思考
对于.NET的分布式应用开发,可以供我们选择的技术和框架比较多,例如webservice,.net remoting,MSMQ,WCF等等技术.对于这些技术很多人都不会陌生,即时没有深入的了解,但是肯 ...
- 在ASP.NET WebAPI 中使用缓存【Redis】
初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...
- 在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)
一.Forms认证 1.在webapi项目中启用Forms认证 Why:为什么要在WebAPI中使用Forms认证?因为其它项目使用的是Forms认证. What:什么是Forms认证?它在WebAP ...
- Asp.Net WebAPI 中Cookie 获取操作方式
1. /// <summary> /// 获取上下文中的cookie /// </summary> /// <returns></returns> [H ...
- Asp.Net WebAPI中Filter过滤器的使用以及执行顺序
转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行 ...
- ASP.NET WebApi 中使用swagger 构建在线帮助文档
1 在Visual Studio 中创建一个Asp.NET WebApi 项目,项目名:Com.App.SysApi(本例创建的是 .net 4.5 框架程序) 2 打开Nuget 包管理软件,查 ...
- [转]在ASP.NET WebAPI 中使用缓存【Redis】
初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...
- ASP.Net WebAPI中添加helppage帮助页面
一.自动创建带帮助的WebAPI 1.首先创建项目的时候选择WebAPI,如下图所示,生成的项目会自动生成帮助文档. 2.设置调用XML文档的代码 3.设置项目注释XML文档生成目录,项目——属性—— ...
- 动态类型和匿名类型在asp.net webapi中的应用
1. 动态类型用于webapi调用 假设需要调用一个webapi,webapi返回了一个json字符串.字符串如下: {"ProductId":"AN002501&qu ...
随机推荐
- Configuration Reference In Vue CLI 3.0
Configuration Reference This project is sponsored by #Global CLI Config Some global configurations ...
- 基于内存,redis,mysql的高速游戏数据服务器设计架构 ZT
zt http://www.cnblogs.com/captainl1993/p/4788236.html 1.数据服务器详细设计 数据服务器在设计上采用三个层次的数据同步,实现玩家数据的高速获取和 ...
- dedecms 安装后 管理后台ie假死 无响应的解决方法
在网站后台(我的是dede)uploads/emplets/index_body.htm中找到并注释掉以下代码: <script type=”text/javascript”>functi ...
- 如何为终端用提供更快的解决方案?让IT技术员具备更高的效率?
- transform.forward和vector3.forward
Vector3.forward的值永远是(0,0,1)(这里的(0,0,1)是世界坐标的(0,0,1)),而transform.forward我们可以理解为其对应物体的z轴方向,是一个向量,而不是一个 ...
- php 超时设置笔记
php.ini default_socket_timeout=5 mysql.connect_timeout = 5 max_execution_time = 5 php-fpm pm = dynam ...
- Fiddler建好代理后,能连到手机,但手机不能上网了是什么原因
依次 tools(工具) >> fiddler options(fiddler选项) >> connections( 连接) >>allow remot ...
- 牛客训练三:处女座的比赛(hash打表)
题目链接:传送门 思路:由于MOD只有9983大小,所以四位小写字母的字符串组合有26+26^2+26^3+26^4=475254种组合. 所以只要每次枚举出从1到475254中的hash值对应的字符 ...
- MFC随笔
设置映射模式 Y轴改为向上 dc.SetMapMode(MM_LOENGLISH);//低精度 dc.SetMapMode(MM_HIENGLISH);//高精度 文本对齐 dc.SetTextAl ...
- 查看Redis集群主从对应关系工具
工具的作用: 1)比"cluster nodes"更为直观的显示结果 2)指出落在同一个IP上的master 3)指出落在同一个IP上的master和slave对 运行效果图: 源 ...