前面讲了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, , 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, , 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, , 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(, , 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。

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

  1. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  2. Web API系列(二)接口安全和参数校验

    以前简单介绍过web api 的设计,但是还是有很多朋友问我,如何合理的设计和实现web api.比如,接口安全,异常处理,统一数据返回等问题.所以有必要系统的总结总结 web api 的设计和实现. ...

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

    本文转自:http://www.cnblogs.com/parry/p/ASPNET_MVC_Web_API_digest_authentication.html 在前一篇文章中,主要讨论了使用HTT ...

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

    在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看另一种验证的方式:digest authentication,即摘要认 ...

  5. ASP.NET Web API系列教程目录

    ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...

  6. Web API系列之三 基本功能实现

    Web API系列之二讲解了如何搭建一个WebApi的基架,本文主要在其基础之上实现基本的功能.下面开始逐步操作: 一.配置WebApi的路由-用于配置外部如何访问内部资源的url的规则 1.添加Gl ...

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

    注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内 ...

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

    本文转自:http://www.cnblogs.com/r01cn/archive/2012/11/11/2765432.html 注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP ...

  9. 【转】ASP.NET WEB API系列教程

    from: 西瓜小强 http://www.cnblogs.com/risk/category/406988.html ASP.NET Web API教程(六) 安全与身份认证 摘要: 在实际的项目应 ...

随机推荐

  1. 安装Ubuntu的那些事儿

    这是博主第一次写博客,本人虽然目前就读的专业属计算机,但目前也是属于新手上路的那一类人.正好不久前解决了一个困扰了我很久的问题 ,现在拿出来给大家分享一下. 上个学期学校的工作室给大家集中普及linu ...

  2. vsftpd安装配置 530 Permission denied.错误

    yum install vsftpd service vsftpd start 530 Permission denied.错误 /etc/vsftpd/user_list    该文件里的用户账户在 ...

  3. nginx+php-fpm+mysql分离部署详解

    相信大家将这三者部署到同一台主机应该已经不陌生了,今天在这里,给大家演示一下如何将三者部署到三台主机上. 实验系统:CentOS 6.6_x86_64 实验前提:大部分软件使用编译安装,请提前准备好编 ...

  4. Django 前后台的数据传递

    Django 从后台往前台传递数据时有多种方法可以实现. 最简单的后台是这样的: from django.shortcuts import render def main_page(request): ...

  5. Spark机器学习· 实时机器学习

    Spark机器学习 1 在线学习 模型随着接收的新消息,不断更新自己:而不是像离线训练一次次重新训练. 2 Spark Streaming 离散化流(DStream) 输入源:Akka actors. ...

  6. Ajax语法浅析

    Ajax是目前很普遍的一门技术,也是很值得探讨和研究的一门技术.本文将针对Ajax的发展过程并结合其在不同库框架中的使用方式来和大家分享下Ajax的那些新老语法. Ajax简介 Ajax全称为“Asy ...

  7. dubbox 增加google-gprc/protobuf支持

    好久没写东西了,今年实在太忙,基本都在搞业务开发,晚上来补一篇,作为今年的收官博客.google-rpc 正式发布以来,受到了不少人的关注,这么知名的rpc框架,不集成到dubbox中有点说不过去. ...

  8. [LeetCode] Add Digits 加数字

    Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. ...

  9. [LeetCode] Combinations 组合项

    Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...

  10. 对于一个div下两个横内元素对其或者居中的方法

    我们会经常遇到这样的对其问题图片和文字,或者文字和单选按钮之类的,而且,如果文字不是12px或者14px,有时候想大一点的时候,会出现对不起的情况或者居中不了. 下面我们来看看: 有时候会出现: 这种 ...