如何友好的处理 WebApi 中抛出的错误

微软的 ASP.NET Web API 是一个轻量级的web框架,可用来构建基于 http 无状态的rest服务,异常是一种运行时错误,异常处理是一种处理运行时错误的技术,每一个开发者都应该知道如何处理 Web API 中的异常,并且在 Action 中使用合适的 错误码错误信息 进行包装。

WebAPI 中的 HttpResponseException

你可以在 Action 中使用 HttpResponseException 来包装指定的 HttpCode 和 HttpMessage,如下例子所示:


public Employee GetEmployee(int id)
{Employee emp = employeeRepository.Get(id);if (emp == null){var response = new HttpResponseMessage(HttpStatusCode.NotFound){Content = new StringContent("Employee doesn't exist", System.Text.Encoding.UTF8, "text/plain"),StatusCode = HttpStatusCode.NotFound}throw new HttpResponseException(response);}return emp;
}

如果你的 Action 返回的是 IHttpActionResult,那么可将 GetEmployee() 方法修改如下:


public IHttpActionResult GetEmployee(int id)
{Employee emp = employeeRepository.Get(id);if (emp == null){var response = new HttpResponseMessage(HttpStatusCode.NotFound){Content = new StringContent("Employee doesn't exist", System.Text.Encoding.UTF8, "text/plain"),StatusCode = HttpStatusCode.NotFound}throw new HttpResponseException(response);}return Ok(emp);
}

从上面的代码可以看出,错误码 和 错误消息 都赋给了 Response 对象,然后包装到了 HttpResponseException 进行返回。

WebAPI 中使用 HttpError

除了直接实例化 HttpResponseMessage 类,还可以使用 Request.CreateErrorResponse() 快捷的创建 HttpResponseMessage 类,如下代码所示:


public IActionResult GetEmployee(int id)
{Employee emp = employeeRepository.Get(id);if (emp == null){string message = "Employee doesn't exist";throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, message));}return Ok(emp);
}

WebAPI 中使用 异常过滤器

异常过滤器是一种可以在 WebAPI 中捕获那些未得到处理的异常的过滤器,要想创建异常过滤器,你需要实现 IExceptionFilter 接口,不过这种方式比较麻烦,更快捷的方法是直接继承 ExceptionFilterAttribute 并重写里面的 OnException() 方法即可,这是因为 ExceptionFilterAttribute 类本身就实现了 IExceptionFilter 接口,如下代码所示:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]public abstract class ExceptionFilterAttribute : FilterAttribute, IExceptionFilter, IFilter{protected ExceptionFilterAttribute();public virtual void OnException(HttpActionExecutedContext actionExecutedContext);public virtual Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken);}

下面的代码片段展示了如何通过重写 ExceptionFilterAttribute.OnException() 方法来创建一个自定义异常过滤器,请注意下面的代码是如何捕获在 Action 中抛出的异常,并将捕获到的异常转换为 HttpStatusResponse 实体,然后塞入合适的 httpcode 和 httpmessage,如下代码所示:

public class CustomExceptionFilter : ExceptionFilterAttribute{public override void OnException(HttpActionExecutedContext actionExecutedContext){HttpStatusCode status = HttpStatusCode.InternalServerError;String message = String.Empty;var exceptionType = actionExecutedContext.Exception.GetType();if (exceptionType == typeof(UnauthorizedAccessException)){message = "Access to the Web API is not authorized.";status = HttpStatusCode.Unauthorized;}else if (exceptionType == typeof(DivideByZeroException)){message = "Internal Server Error.";status = HttpStatusCode.InternalServerError;}else{message = "Not found.";status = HttpStatusCode.NotFound;}actionExecutedContext.Response = new HttpResponseMessage(){Content = new StringContent(message, System.Text.Encoding.UTF8, "text/plain"),StatusCode = status};base.OnException(actionExecutedContext);}}

接下来将自定义的异常过滤器添加到 HttpConfiguration 全局集合中,如下代码所示:

public static void Register(HttpConfiguration config){config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });config.Formatters.Remove(config.Formatters.XmlFormatter);config.Filters.Add(new CustomExceptionFilter());}

除了将自定义异常设置到全局上,你还可以缩小粒度到 Controller 或者 Action 级别上,下面的代码分别展示了如何将其控制在 Action 和 Controller 上。


[DatabaseExceptionFilter]
public class EmployeesController : ApiController
{//Some code
}[CustomExceptionFilter]public IEnumerable<string> Get(){throw new DivideByZeroException(); }

ASP.NET Web API 提供了强大的 HttpResponseException 来包装异常信息,默认情况下,当 WebAPI 中抛出异常,系统默认使用 Http StateCode = 500 作为回应,也即:Internal Server Error. ,场景就来了,如果你会用 HttpResponseException 的话,就可以改变这种系统默认行为,自定义错误码和错误信息让结果更加清晰语义化。

译文链接:https://www.infoworld.com/article/2994111/how-to-handle-errors-in-aspnet-web-api.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

纯c语言实现的改进暗通道去雾算法测试程序(附赠大量测试图像),基于改进暗通道先验算法的图像去雾...

邱清辉摘要&#xff1a;针对普通暗通道先验算法去雾能力的不足&#xff0c;本文提出了一种改进算法&#xff0c;通过采用高斯平滑将原图像分为基础子图和细节子图&#xff0c;基础子图采用暗通道先验算法&#xff0c;细节子图采用gamma变换方法&#xff0c;再采用图像融合进行融…

第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf

第九届蓝桥杯单片机组省赛试题“彩灯控制器”的程序设计与调试 (70 分)一、基本要求1.1 使用CT107D 单片机竞赛板&#xff0c;完成“彩灯控制器”功能的程序设计与调试&#xff1b;1.2 设计与调试过程中&#xff0c;可参考组委会提供的“资源数据包”&#xff1b;1.3 Keil 工程…

为什么离开学校后,学习能力直线下降?

最近几年&#xff0c;人工智能浪潮层层推进&#xff0c;对各大科技公司产生巨大影响。百度推出Apollo无人车计划&#xff0c;阿里建立达摩院&#xff0c;腾讯成立的AI Lab虽布局较晚却也不甘人后。ChinaAI已是大势所趋&#xff0c;吸引的不仅是大公司&#xff0c;更有许多人工智…

android6.0重力工具箱,重力工具箱 GravityBox For Android8.0/8.1(Oreo)稳定版发布!

作为功能最强大的Xposed框架模块之一&#xff0c;重力工具箱 GravityBox的更新适配一直也是最积极的&#xff0c;本次发布的8.x专用版本也算是比较及时&#xff0c;每一个大的Android版本&#xff0c;重力工具箱基本都会有一个专门的版本来适配&#xff0c;当然基础功能也会略有…

如何在 ASP.Net Core 中使用 MediatR

MediatR 是一个 中介者模式 的.NET开源实现&#xff0c; 中介者模式 管控了一组对象之间的相互通讯并有效的减少了对象之间错综复杂的相互依赖&#xff0c;在 中介者模式 中&#xff0c;一个对象不需要直接和另一个对象进行通讯&#xff0c;而是通过 中介者 进行转达&#xff0…

pythonjson数据提取_python爬虫学习笔记(十)-数据提取之JsonPath的使用

1. JSON与JsonPATHJSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景&#xff0c;比如网站前台与后台之间的数据交互。JSON和XML的比较可谓不相上下。Pyt…

全球100款大数据工具汇总(前50款)

01 Talend Open Studio是第一家针对的数据集成工具市场的ETL(数据的提取Extract、传输Transform、载入Load)开源软件供应商。Talend的下载量已超过200万人次&#xff0c;其开源软件提供了数据整合功能。其用户包括美国国际集团&#xff08;AIG&#xff09;、康卡斯特、电子港湾…

NLP快速入门:手把手教你用HanLP做中文分词

导读&#xff1a;随着自然语言处理(Natural Language Processing, NLP)技术日趋成熟&#xff0c;实现中文分词的工具也越来越多。中文分词技术作为中文自然语言处理的第一项核心技术&#xff0c;是众多上层任务的首要基础工作&#xff0c;同时在日常的工作中起着基础性的作用。…

微信小程序android错误,app安卓端 跳转到微信小程序失败

详细问题描述(DCloud产品不会有明显的bug&#xff0c;所以你遇到的问题大都是在特定环境下才能重现的问题&#xff0c;请仔细描述你的环境和重现方式&#xff0c;否则DCloud很难排查解决你的问题)[内容] app安卓端跳转到微信小程序失败重现步骤 一直失败[步骤] 微信小程序关联了…

动态内存(Dynamic Memory),微软的内存过量分配技术?

Hyper-V不支持Memory Overcommitment&#xff0c;一直为VMware和其他虚拟化厂商所诟病。当然&#xff0c;微软一直不承认这是他们的软肋&#xff0c;认为为了保证生产环境VM的性能&#xff0c;过量分配内存是不合时宜的。但是&#xff0c;微软的态度似乎突然转变&#xff0c;3月…

openlayers地图旋转_OpenLayers的使用---- 一个完全免费开源的地图JS库

OpenLayers很容易的在网站里放置动态地图。它能显示展开图及从资源中加载地图标记及矢量数据。它被开发出尽可能的使用所有的地图信息。并且它是完全免费及开源的.详细了解可去它的官网&#xff1a;http://openlayers.org/简单使用&#xff0c;如展示一个块地图.mymap {height:…

程序员上帝视角解读“旅行青蛙”,你的呱真的在旅行嘛?

来源&#xff1a;知乎作者&#xff1a;黄小秋原文链接&#xff1a;https://www.zhihu.com/question/68733553/answer/305463907导语&#xff1a;知乎有位程序员大佬&#xff0c;为了让老母亲老父亲们理解自己的呱究竟在干什么&#xff0c;于是花了五个晚上逆向游戏程序逻辑&…

android.mk 翻译,翻译ANDROID-MK.TXT

Android.mk编译文件是用来向Android NDK描述你的C,C源代码文件的&#xff0c;这篇文档描述了它的语法。在阅读下面的内容之前&#xff0c;假定你已经阅读了docs/OVERVIEW.TXT文件&#xff0c;了解了它们的脚色和用途。概述:一个Android.mk file用来向编译系统描述你的源代码。具…

我为什么对TypeScript由黑转粉?

喜欢就关注我们吧&#xff01;一名曾仅使用 JavaScript 的开发者解释自己为何从反对 TypeScript 到转变为 TypeScript 粉丝。Chirag Swadia 自称曾是 Anti-TypeScript 的 JavaScript 开发者。谈及反对的原因&#xff0c;他以前一直认为给函数/变量添加类型以满足 TypeScript 编…

谈谈关于MVP模式中V-P交互问题

在差不多两年的时间内&#xff0c;我们项目组几十来号人都扑在一个项目上面。这是一个基于微软SCSF&#xff08;Smart Client Software Factory&#xff09;的项目&#xff0c;客户端是墨尔本一家事业单位。前两周&#xff0c;我奉命负责对某个模块进行Code Review工作&#xf…

ofdm解调算法_OFDM系统中固定频偏算法

加入固定频偏&#xff1a;function berMatrix freqOffsetOFDM(BPS,NS,M,SNR,ifftsize,carriers,N,ep)%标准OFDM系统input_bit_stream sign(randn(1,BPS*NS));input_bit_stream(input_bit_stream -1)0;parallel_data StoP(input_bit_stream ,M);% 串并转换%QAM调制modulated_d…

重磅!阿里开源AI核心技术,95%算法工程师受用

你是否曾有过这样的疑虑&#xff1a;人工智能大热&#xff0c;作为一名传统程序员&#xff0c;该如何转型或学习&#xff1f;网上AI教程、书籍&#xff0c;质量参差不齐&#xff0c;如何找到真正专业的资源&#xff1f;AI理论遍地皆是&#xff0c;但几乎都在纸上谈兵。我们该从…

android 换机 iphone8,最好的换机之选?iPhone8 PLUS众测体验

最好的换机之选&#xff1f;iPhone8 PLUS众测体验2017-11-11 14:29:0034点赞1收藏0评论文章前面说一下&#xff0c;自己水平有限文笔不好&#xff0c;没有相机&#xff0c;开箱图这些都是手头的iPhone6和本次众测的的产品拍摄&#xff0c;再加上最近白天都没空拍照&#xff0c;…

阿里开始招聘.NET,要求WPF!

说到WPF、上位机&#xff0c;很多.NET开发者可能只是听过并不了解&#xff0c;然而随着工业4.0的火爆大势&#xff0c;当下.NET开发者又多了一个高薪选型&#xff0c;在各大招聘网站上都能找到5年经验25k左右的岗位&#xff0c;强烈推荐大家关注一波。这里借用了下阿里影业对.N…

eeprom stm8l 擦除 读写_[STM8L]EEPROM操作读与写

原标题&#xff1a;[STM8L]EEPROM操作读与写带有片上EEPROM&#xff0c;常用来保存参数&#xff0c;事实上STM8L整个程序存储区都可以用于作为EEPROM&#xff0c;只是默认情况下被闭了。不同型号的STM8L器件其内部默认划分的EEPROM区域都是从0x1000地址开始&#xff0c;以下为S…