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

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

注:本文是【ASP.NET Web API系列教程】的一部分,如果您是第一次看本系列教程,请先看前面的内容。

Exception Handling in ASP.NET Web API
ASP.NET Web API中的异常处理

本文引自:http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling

By Mike Wasson | March 12, 2012
作者:Mike Wasson | 日期:2012-3-12

This article describes error and exception handling in ASP.NET Web API.
本文描述ASP.NET Web API中的错误与异常处理:

  • HttpResponseException
  • Exception Filters
    异常过滤器
  • Registering Exception Filters
    注册异常过滤器
  • HttpError

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.
如果一个Web API控制器抛出一个未捕捉异常,会发生什么?默认地,大多数异常都会被转化成一个带有状态码“500 – 内部服务器错误”的HTTP响应。

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.
HttpResponseException(HTTP响应异常)类型是一种特殊的情况。这种异常会返回你在异常构造器中指定的任何HTTP状态码。例如,在以下方法中,如果id参数非法,会返回“404 — 未找到”。

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:
为了对响应进行更多控制,你也可以构造整个响应消息,并用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 filter),你可以定制Web API如何处理异常。当一个控制器抛出一个非HttpResponseException异常的未处理异常时,会执行一个异常过滤器。HttpResponseException类型一个特殊的情况,因为它是专门设计用来返回一个HTTP响应的。

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.
异常过滤器实现System.Web.Http.Filters.IExceptionFilter接口。编写异常过滤器最简单的方式是通过System.Web.Http.Filters.ExceptionFilterAttribute类进行派生,并重写其OnException方法。

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.
ASP.NET Web API中的异常过滤器要比ASP.NET MVC中的简单些。然而,这两者是在不同的命名空间中声明的,且是功能独立的。特别是MVC中使用的HandleErrorAttribute类不会处理Web API控制器中抛出的异常。

Here is a filter that converts NotImplementedException exceptions into HTTP status code 501, Not Implemented:
以下是将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); 
            } 
        } 
    } 
}

The Response property of the HttpActionExecutedContext object contains the HTTP response message that will be sent to the client.
HttpActionExecutedContext对象的Response属性含有将发送给客户端的HTTP响应消息。

Registering Exception Filters
注册异常过滤器

There are several ways to register a Web API exception filter:
以下是注册Web API异常过滤器的几种方式:

  • 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.Filters collection. Exeption filters in this collection apply to any Web API controller action.
要全局性地把过滤器运用于所有Web API控制器,将该过滤器的一个实例添加到GlobalConfiguration.Configuration.Filters集合。这个集合中的异常过滤器会运用于任何Web API控制器动作。

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 the WebApiConfig class, which is located in the App_Start folder:
如果用的是“ASP.NET MVC 4 Web应用程序”项目模板创建的项目,要把你的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

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:
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); 
        HttpError err = new HttpError(message); 
        return Request.CreateResponse(HttpStatusCode.NotFound, err); 
    } 
    else 
    { 
        return Request.CreateResponse(HttpStatusCode.OK, item); 
    } 
}

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响应中返回产品。但如果所请求的产品未找到,则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" 
}

Notice that the HttpError was serialized to JSON in this example. One advantage of using HttpError is that it goes through the same content-negotiation and serialization process as any other strongly-typed model.
注意,在这个例子中,HttpError会被序列化成JSON。使用HttpError的一个好处是,与其它强类型模型一样,会进行同样的“内容协商”(本系列化教程的第6.2小节 — 译者注)和序列化过程。

Instead of creating the HttpError object directly, you can use the CreateErrorResponse method:
替代直接创建HttpError对象的一种办法是,你可以使用CreateErrorResponse方法:

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.
CreateErrorResponse是在System.Net.Http.HttpRequestMessageExtensions类中定义的一个扩展方法。本质上,CreateErrorResponse会创建一个HttpError实例,然后创建一个包含该HttpErrorHttpResponseMessage

HttpError and Model Validation
HttpError与模型验证

For model validation, you can pass the model state to CreateErrorResponse, to include the validation errors in the response:
对于模型验证,你可以把模型状态传递给CreateErrorResponse,以便在响应中包含验证错误:

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.
关于模型验证的更多信息,参阅“ASP.NET Web API中的模型验证”(本系列教程的第6.4小节 — 译者注)。

Adding Custom Key-Values to HttpError
将自定义“键-值”添加到HttpError

The HttpError class is actually a key-value collection (it derives from Dictionary<string, object>), so you can add your own key-value pairs:
HttpError类实际上是一个“键-值”集合(它派生于Dictionary<string, object>),因此你可以添加自己的“键-值”对:

public HttpResponseMessage GetProduct(int id) 
{ 
    Product item = repository.Get(id); 
 
    if (item == null) 
    { 
        var message = string.Format("Product with id = {0} not found", id); 
        var err = new HttpError(message); 
        err["error_sub_code"] = 42; 
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, err); 
    } 
    else 
    { 
        return Request.CreateResponse(HttpStatusCode.OK, item); 
    } 
}

Using HttpError with HttpResponseException
以HttpResponseException来使用HttpError

The previous examples return an HttpResponseMessage message from the controller action, but you can also use HttpResponseException to 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:
前面的例子是从控制器动作返回一个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; 
    } 
}

 

看完此文如果觉得有所收获,请给个推荐

 

目录
相关文章
|
21天前
|
人工智能 API 开发工具
【重磅发布】 免费领取阿里云百炼AI大模型100万Tokens教程出炉,API接口实战操作,DeepSeek-R1满血版即刻体验!
阿里云百炼是一站式大模型开发及应用构建平台,支持开发者和业务人员轻松设计、构建大模型应用。通过简单操作,用户可在5分钟内开发出大模型应用或在几小时内训练专属模型,专注于创新。
463 88
【重磅发布】 免费领取阿里云百炼AI大模型100万Tokens教程出炉,API接口实战操作,DeepSeek-R1满血版即刻体验!
|
24天前
|
机器学习/深度学习 人工智能 Serverless
👉「免费满血DeepSeek实战-联网搜索×Prompt秘籍|暨6平台横评」
满血 DeepSeek 免费用!支持联网搜索!创作声明:真人攥写-非AI生成,Written-By-Human-Not-By-AI
2529 9
👉「免费满血DeepSeek实战-联网搜索×Prompt秘籍|暨6平台横评」
|
1月前
|
JSON 数据可视化 API
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
1月前
|
缓存 自然语言处理 安全
快速调用 Deepseek API!【超详细教程】
Deepseek 强大的功能,在本教程中,将指导您如何获取 DeepSeek API 密钥,并演示如何使用该密钥调用 DeepSeek API 以进行调试。
|
1月前
|
存储 人工智能 安全
如何调用 DeepSeek-R1 API ?图文教程
首先登录 DeepSeek 开放平台,创建并保存 API Key。接着,在 Apifox 中设置环境变量,导入 DeepSeek 提供的 cURL 并配置 Authorization 为 `Bearer {{API_KEY}}`。通过切换至正式环境发送请求,可实现对话功能,支持流式或整体输出。
1836 15
|
3月前
|
网络协议 API
检测指定TCP端口开放状态免费API接口教程
此API用于检测指定TCP端口是否开放,支持POST/GET请求。需提供用户ID、KEY、目标主机,可选指定端口(默认80)和地区(默认国内)。返回状态码、信息提示、检测主机、端口及状态(开放或关闭)。示例中ID和KEY为公共测试用,建议使用个人ID和KEY以享受更高调用频率。
92 14
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET Web Pages - 教程
ASP.NET Web Pages 是一种用于创建动态网页的开发模式,采用HTML、CSS、JavaScript 和服务器脚本。本教程聚焦于Web Pages,介绍如何使用Razor语法结合服务器端代码与前端技术,以及利用WebMatrix工具进行开发。适合初学者入门ASP.NET。
|
7天前
|
机器学习/深度学习 开发框架 API
Python 高级编程与实战:深入理解 Web 开发与 API 设计
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧以及数据科学和机器学习。本文将深入探讨 Python 在 Web 开发和 API 设计中的应用,并通过实战项目帮助你掌握这些技术。
|
3月前
|
前端开发 安全 JavaScript
2025年,Web3开发学习路线全指南
本文提供了一条针对Dapp应用开发的学习路线,涵盖了Web3领域的重要技术栈,如区块链基础、以太坊技术、Solidity编程、智能合约开发及安全、web3.js和ethers.js库的使用、Truffle框架等。文章首先分析了国内区块链企业的技术需求,随后详细介绍了每个技术点的学习资源和方法,旨在帮助初学者系统地掌握Dapp开发所需的知识和技能。
2025年,Web3开发学习路线全指南
|
4月前
|
存储 前端开发 JavaScript
如何在项目中高效地进行 Web 组件化开发
高效地进行 Web 组件化开发需要从多个方面入手,通过明确目标、合理规划、规范开发、加强测试等一系列措施,实现组件的高效管理和利用,从而提高项目的整体开发效率和质量,为用户提供更好的体验。
126 63

热门文章

最新文章