[翻译] 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 ...
随机推荐
- socket的同步异步的性能差别,以及listen的参数backlog
先说listen的参数backlog,同步系统中分别设置为5,512,1024的跑分情况 跑分工具apache的ab,参数为:ab -n50000 -c300 backlog=5跑分结果 Reques ...
- 通过flask中的Response返回json数据
使用flask的过程中,发现有时需要生成一个Response并返回.网上查了查,看了看源码,找到了两种办法: from flask import Response, json Response(jso ...
- mysql 5.7 linux环境下解压安装
在CentOS linux环境安装mysql 一般rpm(或者yum),预编译和源码安装. 如果采用rpm或者yum安装,mysql的数据文件一般存放在/var/lib/mysql目录下,也就是会把d ...
- 2017-2018-1 20155312《信息安全技术》实验二——Windows口令破解实验报告
2017-2018-1 20155312<信息安全技术>实验二--Windows口令破解实验报告 实验目的 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破 ...
- 2017年多校get点
杨辉三角形变形??? lucas定理
- Java crash问题分析
Java的应用有时候会因为各种原因Crash,这时候会产生一个类似java_errorpid.log的错误日志.可以拿到了 这个日志,怎样分析Crash的原因呢?下面我们来详细讨论如何分析java_e ...
- 一窥kbmmw中的 smart service
在kbmmw 的新版中(还没有发布),将会有一个叫做smart service 的服务.这种服务的属性基于服务器端,并且可以自动注册服务名,下面就是一个简单例子代码.这个服务里面有有三个发布的函数:e ...
- Idea中如何将web项目打包成war包并放到tomcat中启动
第一步:在idea中选中Artifacts.右侧勾选Build on make生成war包,如下图 第二步:将target文件夹里面的war包拷贝到tomcat文件下的webapp目录下 第三步:修改 ...
- 使用Ant发布web应用到tomcat
使用Ant发布web应用到tomcat 来自:http://blog.csdn.net/hbcui1984/article/details/1954537 今天在公司用ant写了个部署web应用的脚本 ...
- 6-具体学习git--分支冲突,rebase|| stash 临时修改
rebase很危险. https://morvanzhou.github.io/tutorials/others/git/