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

Web API统一异常处理 【转载】的更多相关文章

  1. [Web API] 如何让 Web API 统一回传格式以及例外处理[转]

    [Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...

  2. [Web API] 如何让 Web API 统一回传格式以及例外处理

    [Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...

  3. Web APi之异常处理(Exception)以及日志记录(NLog)(十六)

    前言 上一篇文章我们介绍了关于日志记录用的是Log4net,确实也很挺强大,但是别忘了我们.NET有专属于我们的日志框架,那就是NLog,相对于Log4net而言,NLog可以说也是一个很好的记录日志 ...

  4. ASP.NET Web Api 安全性(转载)

    转载地址:http://www.cnblogs.com/fzrain/p/3552423.html 在Web Api中强制使用Https 我们可以在IIS级别配置整个Web Api来强制使用Https ...

  5. Exception Handling in ASP.NET Web API webapi异常处理

    原文:http://www.asp.net/web-api/overview/error-handling/exception-handling This article describes erro ...

  6. ASP.Net Web API 输出缓存 转载 -- Output caching in ASP.NET Web API

    一.Nuget安装相关dll Web API 2 : Install-Package Strathweb.CacheOutput.WebApi2 Web API 1 : Install-Package ...

  7. Spring Boot中Web应用的统一异常处理 转载来自翟永超

    我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来 ...

  8. web API 的异常处理

    实现自定义的异常处理类 --------------------------------------------------------------------- public class MyExc ...

  9. 微信小程序的Web API接口设计及常见接口实现

    微信小程序给我们提供了一个很好的开发平台,可以用于展现各种数据和实现丰富的功能,通过小程序的请求Web API 平台获取JSON数据后,可以在小程序界面上进行数据的动态展示.在数据的关键 一环中,我们 ...

随机推荐

  1. 在linux执行kettle

    1.下载 最新版下载 7.1 https://community.hitachivantara.com/docs/DOC-1009855 2.准备 3.上传任务文件 .kjb,.ktr 4.上传mys ...

  2. Final阶段第1周/共1周 Scrum立会报告+燃尽图 07

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2486] 版本控制:https://git.coding.net/liuyy08 ...

  3. 爬虫系列5:scrapy动态页面爬取的另一种思路

    前面有篇文章给出了爬取动态页面的一种思路,即应用Selenium+Firefox(参考<scrapy动态页面爬取>).但是selenium需要运行本地浏览器,比较耗时,不太适合大规模网页抓 ...

  4. 2016 多校联赛7 Elegant Construction

    Being an ACMer requires knowledge in many fields, because problems in this contest may use physics, ...

  5. Python学习笔记第十周

    目录: 一.基础概念 1.多进程 2.进程间通信 3.进程锁 4.进程池 5.协程 a) greenlet b) Gevent 6.论事件驱动与异步IO 7.IO多路复用 8.Python Selec ...

  6. 移动APP漏洞趋势

    个人总结,可能片面或不正确 样本来自WooYun网站,截止15年12月19号,一共75650个漏洞: 一.Top10安全漏洞中,sql注入占1/3:可见如果你是sql注入方面的测试专家,web安全1/ ...

  7. thinkphp+redis实现秒杀功能(转)

    1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: ...

  8. MySQL中的修改表操作

    一.增加表的列 语法:alter table 表名 add(           增加列定义          ); 实例: #增加列 alter table text add( text_num ) ...

  9. C++ 中时钟函数的使用

    头文件: #incllude <time.h> 定义: clock_t var1, var2; 获取时间: var1 = clock(); 每过千分之一秒(1毫秒),调用clock()函数 ...

  10. [LeetCode&Python] Problem 453. Minimum Moves to Equal Array Elements

    Given a non-empty integer array of size n, find the minimum number of moves required to make all arr ...