Web API系列(三)统一异常处理

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03



  前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,《Web API系列(二)接口安全和参数校验》,本文主要介绍Web API异常结果的处理。作为内部或者是对外提供的统一webapi 接口,统一的异常处理,把正确的信息返回给调用者很重要。这样可以让接口开发人员,了解具体的原因所在,这样可以得到有效的错误处理。

  需要注意的是,webapi异常的状态码,尽量不要和业务状态码混淆。可以分为两个不同的字段,或者是状态码的规则不同。相关返回数据的格式,可以参考,前面的文章。

1、常规程序异常处理

  常规的程序异常,指的是webapi 接口程序在执行的时候出现的各种异常情况,可以使用异常筛选器捕获所有异常。

  1. API自定义错误过滤器属性:ApiExceptionAttribute

    /// <summary>
    /// API自定义错误过滤器属性
    /// </summary>
    public class ApiExceptionHandlingAttribute : ExceptionFilterAttribute
    {
        /// <summary>
        /// 统一对调用异常信息进行处理,返回自定义的异常信息
        /// </summary>
        /// <param name="context">HTTP上下文对象</param>
        public override void OnException(HttpActionExecutedContext context)
        {
            //自定义异常的处理
            if (context.Exception is NotImplementedException)
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotImplemented)
                {
                    //封装处理异常信息,返回指定JSON对象
                    Content = new StringContent(JsonHelper.ToJson(new ErrorModel((int)HttpStatusCode.NotImplemented, 0, ex.Message)), Encoding.UTF8, "application/json"),
                    ReasonPhrase = "NotImplementedException"
                });
            }
            else if (context.Exception is TimeoutException)
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.RequestTimeout)
                {
                    //封装处理异常信息,返回指定JSON对象
                    Content = new StringContent(JsonHelper.ToJson(new ErrorModel((int)HttpStatusCode.RequestTimeout, 0, ex.Message)), Encoding.UTF8, "application/json"),
                    ReasonPhrase = "TimeoutException"
                });
            }
            //.....这里可以根据项目需要返回到客户端特定的状态码。如果找不到相应的异常,统一返回服务端错误500
            else
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    //封装处理异常信息,返回指定JSON对象
                    Content = new StringContent(JsonHelper.ToJson(new ErrorModel((int)HttpStatusCode.InternalServerError, 0, ex.Message)), Encoding.UTF8, "application/json"),
                    ReasonPhrase = "InternalServerErrorException"
                });
            }

            //base.OnException(context);

            //记录关键的异常信息
            //Debug.WriteLine(context.Exception);
        }
    }

  2. 定义好了错误过滤器,根据实际情况,在不同级别使用统一的异常处理机制。比如,接口action级别,控制器Controller级别或者是全局。

  我们目前的使用的是全局进行异常过滤。在ApiBase 增加异常过滤。

 [ApiAuth] [ApiExceptionHandling] public class ApiBase : ApiController

2、地址接口异常处理

  对于常规的异常,我们通过上面的处理方式,就可以很好进行拦截并处理了,如果接口异常是全局性的,如访问地不正确,或者调用的接口就不是有效的地址,这样的话,返回的信息就不会被上面的拦截器进行处理了。

如我们给一个无效的API调用路径,在浏览器中获得下面错误结果。

  由于上面结果就无法被我们的常规异常拦截器所捕获,因此不会输出经过封装好的异常信息。

  所以如果需要拦截,我们需要增加自己的消息代理处理,用来捕获这些特殊的异常信息。

 /// <summary>
    /// API自定义错误消息处理委托类。 /// 用于处理访问不到对应API地址的情况,对错误进行自定义操作。 /// </summary>
    public class CustomErrorMessageDelegatingHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) => { HttpResponseMessage response = responseToCompleteTask.Result; HttpError error = null; if (response.TryGetContentValue<HttpError>(out error)) { //添加自定义错误处理 //error.Message = "Your Customized Error Message";
 } if (error != null) { //获取抛出自定义异常,有拦截器统一解析
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound) { //封装处理异常信息,返回指定JSON对象
                        Content = new StringContent(JsonHelper.ToJson(new ErrorModel(404, 0, error.Message)), Encoding.UTF8, "application/json"), ReasonPhrase = "Exception" }); } else { return response; } }); } }

  同时,在WebApiConfig中,注册上相关处理

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { .............. config.MessageHandlers.Add(new CustomErrorMessageDelegatingHandler());

  有了以上这两种异常处理,我们就可以统一我们的调用规则,并进行异常记录和显示了,非常方便。

3、总结

  首先,以上这两种异常处理,我们就可以统一我们的调用规则,但是对于WebApi里面异常的处理机制,可能还不够深入,但对于一般项目的异常处理基本够用。其他朋友,如果还有什么更好的方案,还望不吝赐教,感谢感谢!

  其次,我们目前使用的异常处理,参考于http://www.cnblogs.com/wuhuacong/p/4843422.html。

参考页面:http://qingqingquege.cnblogs.com/p/5933752.html

时间: 2024-10-24 03:19:19

Web API系列(三)统一异常处理的相关文章

ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)

在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看另一种验证的方式:digest authentication,即摘要认证. 系列文章列表 ASP.NET Web API(一):使用初探,GET和POST数据ASP.NET Web API(二):安全验证之使用HTTP基本认证ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication) 摘要认证原理 在基本认证的方式中,主

ASP.NET Web API系列教程(目录)(转)

注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内对此关注的人似乎还不多,有关ASP.NET Web API的文章也不多见.为此,本人打算对微软ASP.NET Web API官方网站上的一些教程进行翻译,以期让更多的国人了解.学习和使用这项ASP.NET Web API. ASP.NET Web API系列教程目录 Introduction:Wha

ASP.NET Web API系列教程目录

ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Started with ASP.NET Web API第1章 ASP.NET Web API入门 Your First Web API (C#)第一个Web API(C#) Deep Dive into Web API深入探讨Web API(这是一个视频教程,本翻译系列略) Pro ASP.NET Web

Web Api系列教程第2季(OData篇)(二)&mdash;&mdash;使用Web Api创建只读的OData服务

前言 很久没更新了,之前有很多事情,所以拖了很久,非常抱歉.好了,废话不多说,下面开始正题.本篇仍然使用上一季的的项目背景(系列地址http://www.cnblogs.com/fzrain/p/3490137.html)来演示OData服务,因此我们可以直接使用之前建好的数据访问层.但是不是说一定要看到之前的所有内容,我们只是借用数据库访问层,对于数据库的模型构建移步(使用Entity Framework Code First构建数据库模型). 有了数据访问的基础,我们可以开始构建OData服

使用 ASP.NET Core MVC 创建 Web API(三)

原文:使用 ASP.NET Core MVC 创建 Web API(三) 使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 十.添加 GetBookItem 方法 1) 在Visual Studio 2017中的“解决方案资源管理器”中双击打开BookController文件,添加Get方法的API.代码如下. // GET: api/Book [H

Web API系列(三) 异常处理

在上一篇教程中我为大家介绍了Web API中Filter的开发使用,其中讲到ExceptionFilter时留了一个坑:ExceptionFilter只能截获并处理Action执行过程中发生的异常,在Action执行过程之外如果出现异常,ExceptionFilter是无能为力的. 这些异常包括: 1.  Controller构造方法中出现的异常 2.  MessageHandlers中出现的异常 3.  路由过程中出现的异常 4.  Body在序列化/反序列化过程中出现的异常 由此可以看出,E

WEB API 系列(二) Filter的使用以及执行顺序

在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想,通过Filter能统一地对一些通用逻辑进行处理,如:权限校验.参数加解密.参数校验等方面我们都可以利用这一特性进行统一处理,今天我们来介绍Filter的开发.使用以及讨论他们的执行顺序. 一.Filter的开发和调用 在默认的WebApi中,框架提供了三种Filter,他们的功能和运行条件如下表所

[转]Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务

本文转自:http://www.cnblogs.com/fzrain/p/3923727.html 前言 很久没更新了,之前有很多事情,所以拖了很久,非常抱歉.好了,废话不多说,下面开始正题.本篇仍然使用上一季的的项目背景(系列地址http://www.cnblogs.com/fzrain/p/3490137.html)来演示OData服务,因此我们可以直接使用之前建好的数据访问层.但是不是说一定要看到之前的所有内容,我们只是借用数据库访问层,对于数据库的模型构建移步(使用Entity Fram

Web Api 系列(一) 初识 web api

HTTP 不仅仅服务于web 页面,而且它也是一个强大的平台 它对于构建提供开放服务和数据的api 来说.HTTP是简单的,灵活的,无处不在的.几乎所有的平台都存在它的身影.HTTP服务可以贯穿于几乎所有的客户端.包括浏览器,移动设备和传统的桌面程序. ASP.NET Web API 是基于.net Framework 用来构建Web 接口的框架.接下来使用asp.net  web api 构建web 接口来返回产品列表. 演示案例需要的软件版本:vs 2013, web api 2. 一 创建