Web API--自定义异常结果的处理
1、常规的异常处理
统一的异常处理,把正确的信息返回给调用者很重要,可以让接口开发人员或者用户,了解具体的原因所在,这样可以得到有效的错误处理。
参考微信API的处理,微信API,对于调用都有一个错误信息返回,不会直接裸露未经处理的异常,因此它们都是经过了一定的拦截处理,然后把错误信息包装提供给接口调用方的。如下是微信的一些接口处理错误。
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):{"errcode":40013,"errmsg":"invalid appid"}
我们根据自己的需要,定义了一个统一的错误信息实体类,如下所示。
/// <summary>/// 接口返回的错误信息/// </summary>public class BaseResultJson{/// <summary>/// 错误代码/// </summary>public int errcode { get; set; }/// <summary>/// 如果不成功,返回的错误信息/// </summary>public string errmsg { get; set; }/// <summary>/// 是否成功/// </summary>public bool success { get; set; }}
这样我们就可以把拦截到的错误信息,转换为这样一个方便使用的实体类信息了。
拦截Web API的调用异常,一般可以结合Try Catch的方法,以及异常拦截器进行处理,如下是主动抛出的一些异常信息处理。
//如果没有通过,则抛出异常,由异常过滤器统一处理if (!result.success){throw new MyApiException(result.errmsg, result.errcode);}
其中MyApiException是自定义的一个异常信息,用来承载自定义错误信息的异常类。
异常拦截器,我们在Web API里面可以通过Attribute这种标签特性进行处理,如下是我在Web API的基类里面定义了一个异常处理器。
/// <summary>/// 所有接口基类/// </summary>[ExceptionHandling]public class BaseApiController : ApiController
这个特性对象的定义,它的代码如下所示。
/// <summary>/// API自定义错误过滤器属性/// </summary>public class ExceptionHandlingAttribute : ExceptionFilterAttribute{/// <summary>/// 统一对调用异常信息进行处理,返回自定义的异常信息/// </summary>/// <param name="context">HTTP上下文对象</param>public override void OnException(HttpActionExecutedContext context){//自定义异常的处理MyApiException ex = context.Exception as MyApiException;if (ex != null){ throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError){//封装处理异常信息,返回指定JSON对象Content = new StringContent(new BaseResultJson(ex.Message, false, ex.errcode).ToJson()),ReasonPhrase = "Exception"});}//记录关键的异常信息Debug.WriteLine(context.Exception);//常规异常的处理string msg = string.IsNullOrEmpty(context.Exception.Message) ? "接口出现了错误,请重试或者联系管理员" : context.Exception.Message;throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError){Content = new StringContent(msg),ReasonPhrase = "Critical Exception"});}}
根据这些代码,我们就可以实现对调用异常的统一封装处理,让它给我们返回统一的对象信息了,如下是其中一个调用异常,转换为自定义异常信息后的结果输出。
{"errcode":404,"errmsg":"请求的资源不支持 http 方法“POST”。","success":false}
这样我们在处理Web API的返回结果的时候,可以先处理它的异常信息,具体的处理代码如下所示。
HttpHelper helper = new HttpHelper();helper.ContentType = "application/json";string content = helper.GetHtml(url, postData, true);VerifyErrorCode(content);T result = JsonConvert.DeserializeObject<T>(content);return result;
我们在上面红色部分的代码就是先处理异常定义信息,如果有这些异常,我们可以在界面中进行异常处理显示了。
例如,如果自定义异常存在,我们转换后,把对应的信息显示出来,重新抛出异常即可。
BaseResultJson errorResult = JsonConvert.DeserializeObject<BaseResultJson>(content);//非成功操作才记录异常,因为有些操作是返回正常的结果({"errcode": 0, "errmsg": "ok"})if (errorResult != null && !errorResult.success){string error = string.Format("请求发生错误!错误代码:{0},说明:{1}", (int)errorResult.errcode, errorResult.errmsg);LogTextHelper.Error(errorResult.ToJson());throw new Exception(error);//抛出错误}
2、地址接口异常处理
对于常规的异常,我们通过上面的处理方式,就可以很好进行拦截并处理了,如果接口异常是全局性的,如访问地址簿正确,或者参数多了几个信息,那么调用的接口就不是有效的地址,这样的话,返回的信息就不会被上面的拦截器进行处理了。
如我们给一个无效的API调用路径,在浏览器中获得下面错误结果。
上面结果就无法被我们的常规异常拦截器所捕获,因此不会输出经过封装好的异常信息。
如果需要拦截,我们需要增加自己的消息代理处理,用来捕获这些特殊的异常信息。
public static class WebApiConfig{public static void Register(HttpConfiguration config){..............config.MessageHandlers.Add(new CustomErrorMessageDelegatingHandler());
上面红色部分就是我们自己添加的消息代理处理类,用来处理一些特殊的异常信息,如下代码所示。
/// <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(new BaseResultJson(error.Message, false, 404).ToJson()),ReasonPhrase = "Exception"});}else{return response;}});}}
经过了上面的处理后,我们进一步测试一下不存在的地址的异常处理结果,可以看到输出的内容是经过了自定义对象的转换了。
常规的调用,如果接口不对应,那么错误也是类似下面的消息
{"errcode":404,"errmsg":"找不到与请求 URI“http://localhost:9001/api/SystemType/Delete?signature=72f8d706c79dc14d70fc3f080d4706748d754021×tamp=1443194061&nonce=0.650359861855563&appid=website_9A39C2A8&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxIiwiaWF0IjoxNDQzMTk0MDM4LCJqdGkiOiI1YmEyYmE5Ni0yZTA4LTQ1ZTgtYTAwNy01MmY3OTkzYTg2NzEiLCJuYW1lIjoiYWRtaW4iLCJjaGFubmVsIjoiMCIsInNoYXJlZGtleSI6IjEyMzRhYmNkIn0.RRXQmmSCJzDK5Or6rmBL5wjd-YIJoEQFc0pOzqhR6IU”匹配的 HTTP 资源。","success":false}
有了这些信息,我们就可以统一我们的调用规则,并进行异常记录和显示了,非常方便。
http://www.cnblogs.com/wuhuacong/p/4843422.html
Web API--自定义异常结果的处理相关推荐
- Web API系列(三)统一异常处理
前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...
- ASP.NET Web API 2 过滤器
Ø 前言 我们知道 ASP.NET Web API 过滤器,也是属于消息处理机制中的一部分.正因如此,我们经常使用它来完成对请求的授权验证.参数验证,以及请求的 Log 记录,程序异常捕获等. 1. ...
- 【转】Web API项目中使用Area对业务进行分类管理
在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...
- ASP.NET Core 3.1 Web API和EF Core 5.0 中具有泛型存储库和UoW模式的域驱动设计实现方法
目录 介绍 背景 领域驱动设计 存储库模式 工作单元模式 使用代码 创建空白解决方案和解决方案架构 添加和实现应用程序共享内核库 PageParam.cs 在Entity Framework Core ...
- ASP.NET Core和Web API:用于管理异常和一致响应的自定义包装器
目录 介绍 为什么? 怎么做? VMD.RESTApiResponseWrapper Nuget软件包 安装及使用 ASP.NET Core集成 ASP.NET Web API集成 样本响应输出 定义 ...
- Web API应用架构在Winform混合框架中的应用(3)--Winfrom界面调用WebAPI的过程分解...
最近一直在整合WebAPI.Winform界面.手机短信.微信公众号.企业号等功能,希望把它构建成一个大的应用平台,把我所有的产品线完美连接起来,同时也在探索.攻克更多的技术问题,并抽空写写博客,把相 ...
- 在ASP.NET Web API中返回错误的最佳实践
本文翻译自:Best practice to return errors in ASP.NET Web API I have concerns on the way that we returns e ...
- 加速ASP.NET Core WEB API应用程序。 第三部分
深度重构和完善ASP.NET Core WEB API应用程序代码 (Deep refactoring and refinement of ASP.NET Core WEB API applicati ...
- 加快ASP。NET Core WEB API应用程序。第3部分
下载source from GitHub 对ASP进行深度重构和优化.NET Core WEB API应用程序代码 介绍 第1部分.创建一个测试的RESTful WEB API应用程序. 第2部分.增 ...
- Web Api学习一
接触WebApi读的第一篇文章: ASP.NET Web API(一):使用初探,GET和POST数据 实践过程中,用的Fiddler模拟Post请求时收到的对象总是为空null 解决:将文章中的内容 ...
最新文章
- ORACLE SQL笛卡尔集
- [转]Vi/Vim查找替换使用方法
- 如何在运行时更改日志记录级别
- Alexey 大神接棒,YOLOv4 重磅来袭!快来一睹论文真容吧!| 原力计划
- WDK10+VS2015 驱动环境搭建
- hdu1428漫步校园( 最短路+BFS(优先队列)+记忆化搜索(DFS))
- MPPT “最大功率点跟踪”
- 腾讯tdsql如何对接mysql,数据库交付运维高级工程师-腾讯云TDSQL(MySQL版)认证考试(TCE)...
- Java编程思想笔记
- python将数据写入txt文本文件
- python定义空数组_python定义二维数组
- 计算机键盘上删除,电脑哪个是删除键
- ESD介绍及TVS的原理和应用
- 关于键盘右边的 数字小写键盘不能使用的解决办法
- 32位程序使用超过4G的内存
- 可视化项目管理,项目进度管理必备工具
- 陈艾盐:《春燕》百集访谈节目第三十七集
- Android Studio 设置打开layout.xml文件的默认视图
- 嵌入式是什么?为什么引入嵌入式技术?嵌入式技术的优缺点?
- ThinkPhp6+Vue直播平台后台管理系统
热门文章
- OpenGL Blinn-Phong Shader实例
- C语言实现通用堆栈(附完整源码)
- 经典C语言程序100例之八四
- 经典C语言程序100例之七七
- 计算机操作系统作业答案,计算机操作系统作业及答案
- 取消mysql自动备份文件_MySQL自动备份并清理多少天前的备份文件
- proxmoxve打造云桌面_基于PROXMOX VE的家庭NAS搭建方案
- fillstyle属性_html设置或返回用于填充绘画的颜色渐变或模式的属性fillStyle
- 1.18.3.Flink Catalog介绍、Catalog 定义、Catalog 的实现、Catalog 使用举例
- B13_NumPy数学函数(三角函数,舍入函数)