原文链接: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);
}
}

CreateErrorResponseSystem.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 中的异常处理的更多相关文章

  1. 关于ASP.NET WebAPI中HTTP模型的相关思考

    对于.NET的分布式应用开发,可以供我们选择的技术和框架比较多,例如webservice,.net remoting,MSMQ,WCF等等技术.对于这些技术很多人都不会陌生,即时没有深入的了解,但是肯 ...

  2. 在ASP.NET WebAPI 中使用缓存【Redis】

    初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...

  3. 在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)

    一.Forms认证 1.在webapi项目中启用Forms认证 Why:为什么要在WebAPI中使用Forms认证?因为其它项目使用的是Forms认证. What:什么是Forms认证?它在WebAP ...

  4. Asp.Net WebAPI 中Cookie 获取操作方式

    1. /// <summary> /// 获取上下文中的cookie /// </summary> /// <returns></returns> [H ...

  5. Asp.Net WebAPI中Filter过滤器的使用以及执行顺序

    转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行 ...

  6. ASP.NET WebApi 中使用swagger 构建在线帮助文档

    1 在Visual Studio 中创建一个Asp.NET  WebApi 项目,项目名:Com.App.SysApi(本例创建的是 .net 4.5 框架程序) 2  打开Nuget 包管理软件,查 ...

  7. [转]在ASP.NET WebAPI 中使用缓存【Redis】

    初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...

  8. ASP.Net WebAPI中添加helppage帮助页面

    一.自动创建带帮助的WebAPI 1.首先创建项目的时候选择WebAPI,如下图所示,生成的项目会自动生成帮助文档. 2.设置调用XML文档的代码 3.设置项目注释XML文档生成目录,项目——属性—— ...

  9. 动态类型和匿名类型在asp.net webapi中的应用

    1.  动态类型用于webapi调用 假设需要调用一个webapi,webapi返回了一个json字符串.字符串如下: {"ProductId":"AN002501&qu ...

随机推荐

  1. socket的同步异步的性能差别,以及listen的参数backlog

    先说listen的参数backlog,同步系统中分别设置为5,512,1024的跑分情况 跑分工具apache的ab,参数为:ab -n50000 -c300 backlog=5跑分结果 Reques ...

  2. 通过flask中的Response返回json数据

    使用flask的过程中,发现有时需要生成一个Response并返回.网上查了查,看了看源码,找到了两种办法: from flask import Response, json Response(jso ...

  3. mysql 5.7 linux环境下解压安装

    在CentOS linux环境安装mysql 一般rpm(或者yum),预编译和源码安装. 如果采用rpm或者yum安装,mysql的数据文件一般存放在/var/lib/mysql目录下,也就是会把d ...

  4. 2017-2018-1 20155312《信息安全技术》实验二——Windows口令破解实验报告

    2017-2018-1 20155312<信息安全技术>实验二--Windows口令破解实验报告 实验目的 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破 ...

  5. 2017年多校get点

    杨辉三角形变形??? lucas定理

  6. Java crash问题分析

    Java的应用有时候会因为各种原因Crash,这时候会产生一个类似java_errorpid.log的错误日志.可以拿到了 这个日志,怎样分析Crash的原因呢?下面我们来详细讨论如何分析java_e ...

  7. 一窥kbmmw中的 smart service

    在kbmmw 的新版中(还没有发布),将会有一个叫做smart service 的服务.这种服务的属性基于服务器端,并且可以自动注册服务名,下面就是一个简单例子代码.这个服务里面有有三个发布的函数:e ...

  8. Idea中如何将web项目打包成war包并放到tomcat中启动

    第一步:在idea中选中Artifacts.右侧勾选Build on make生成war包,如下图 第二步:将target文件夹里面的war包拷贝到tomcat文件下的webapp目录下 第三步:修改 ...

  9. 使用Ant发布web应用到tomcat

    使用Ant发布web应用到tomcat 来自:http://blog.csdn.net/hbcui1984/article/details/1954537 今天在公司用ant写了个部署web应用的脚本 ...

  10. 6-具体学习git--分支冲突,rebase|| stash 临时修改

    rebase很危险. https://morvanzhou.github.io/tutorials/others/git/