webapi框架搭建系列博客

前言

  上一篇我们已经完成了项目的日志管理,在项目开发中日志会经常记录程序中的异常,供后续问题排查使用。本篇讲如何在webapi里加入异常处理机制。

目的和原则

  1、程序任何地方都不能catch掉异常,如果要catch也请重新throw异常或是将异常记录到日志里。避免异常被“吃掉“,导致无法排查程序的bug。

  2、webapi接口的”请求成功“和”请求失败“以一定的标准规范提供给外部

    我的规范为:

    所有的成功请求返回200(response的status为200),返回的结果以json封装

    所有的失败请求返回非200,错误以json返回,错误的内容为Message的值,如{"Message":"这里是异常的内容描述"}

  3、如果为已知异常(即我们代码里写的throw异常)可简单的记录到日志,但如果是未知异常(我们不知道是哪里抛出的异常,往往也是程序的bug)则记录到特殊的日志文件里,如上篇的log/error目录下。

参考

微软webapi异常处理:https://docs.microsoft.com/zh-cn/aspnet/web-api/overview/error-handling/

步骤如下

自定义异常类

  此异常类即是”已知“异常,约定程序里我们自己抛出的异常都用此类,Message属性记录异常的描述信息

using System;
using System.Runtime.Serialization; namespace webapi.Exceptions
{
public class KnownException : Exception
{
public KnownException():base()
{
} public KnownException(string message) : base(message)
{
} public KnownException(string message, Exception innerException) : base(message, innerException)
{
} protected KnownException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

创建webapi异常过滤器

  创建WebApiExceptionFilterAttribute类,代码如下

using System.Net;
using System.Net.Http;
using System.Web.Http.Filters;
using log4net; namespace webapi.Exceptions
{
public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exception = actionExecutedContext.Exception;//获取产生的异常对象
var exceptionMessage = exception.Message;
var logMessage =
$@"controller.action={actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName}.{actionExecutedContext.ActionContext.ActionDescriptor.ActionName}:exception="
+ exception.Message;//异常内容
ILog log = LogManager.GetLogger(actionExecutedContext.ActionContext.ControllerContext.Controller.GetType());
if (exception is KnownException)
{
log.Debug(logMessage);
}
else
{
log.Error(logMessage, exception);
}
actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, exceptionMessage);
} }
}

  在webapi里使用异常过滤最简单的方法就是继承自ExceptionFilterAttribute类,并重写OnException方法并写入自己的异常处理逻辑

将异常过滤器加到webapi里

修改之前的WebApiConfig.OwinWebApiConfiguration方法,代码如下

/// <summary>
/// 返回webapi的httpconfiguration配置
/// 用于webapi应用于owin技术时使用
/// </summary>
/// <returns></returns>
public static HttpConfiguration OwinWebApiConfiguration(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();//开启属性路由
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filters.Add(new WebApiExceptionFilterAttribute());
return config;
}

  增加的只是config.Filters.Add(new WebApiExceptionFilterAttribute());这一句

测试结果

创建用于测试的控制器,写两个接口分别模拟程序bug抛出的未知异常和自己抛出的已知异常

using System;
using System.Web.Http;
using webapi.Exceptions; namespace webapi.example
{
[RoutePrefix("api/exceptionTest")]
public class ExceptionTestController : ApiController
{
/// <summary>
/// 模拟程序bug抛出的异常
/// </summary>
/// <returns></returns>
[Route("unknown"),HttpGet]
public IHttpActionResult UnKnow()
{
throw new Exception("未知的异常");
}
/// <summary>
/// 模拟主动抛出的业务异常
/// </summary>
/// <returns></returns>
[Route("known"), HttpGet]
public IHttpActionResult Know()
{
throw new KnownException("已知的异常");
}
}
}

  返问两个接口会得到内容为{"Message":"xxx"},status为400的respose,和我们的约定规则一样。

webapi框架搭建-webapi异常处理的更多相关文章

  1. webapi框架搭建系列博客

    webapi框架搭建系列博客 webapi框架搭建-创建项目(一) webapi框架搭建-创建项目(二)-以iis为部署环境的配置 webapi框架搭建-创建项目(三)-webapi owin web ...

  2. webapi框架搭建-依赖注入之autofac

    前言 c#的依赖注入框架有unity.autofac,两个博主都用过,感觉unity比较简单而autofac的功能相对更丰富(自然也更复杂一点),本篇将基于前几篇已经创建好的webapi项目,引入au ...

  3. webapi框架搭建-创建项目(三)-webapi owin

    上一篇:创建项目(二) 在上一篇里,我们已经创建好了webapi应用,并已经部署到iis里,本篇讲如何用owin自宿主或是iis宿主来部署webapi应用. owin介绍 传统的asp.net网站只能 ...

  4. webapi框架搭建-创建项目(二)-以iis为部署环境的配置

    上篇:webapi快速框架搭建-创建项目(一) 在"创建项目(一)"这一篇里已经创建了一个空的项目,但项目上什么都没有,本篇描述如何将webapi配置成部署在iis上. 步骤 用n ...

  5. webapi框架搭建-日志管理log4net

    前言 本篇讲怎么在前几篇已经创建好的项目里加上日志处理机制,我们采用Log4net技术.跟多的log4net技术的细节请查阅log4net的官网. log4net官网:http://logging.a ...

  6. webapi框架搭建-安全机制(四)-可配置的基于角色的权限控制

    webapi框架搭建系列博客 在上一篇的webapi框架搭建-安全机制(三)-简单的基于角色的权限控制,某个角色拥有哪些接口的权限是用硬编码的方式写在接口上的,如RBAuthorize(Roles = ...

  7. webapi框架搭建-安全机制(三)-简单的基于角色的权限控制

    webapi框架搭建系列博客 上一篇已经完成了“身份验证”,如果只是想简单的实现基于角色的权限管理,我们基本上不用写代码,微软已经提供了authorize特性,直接用就行. Authorize特性的使 ...

  8. webapi框架搭建-安全机制(二)-身份验证

    webapi框架搭建系列博客 身份验证(authentication)的责任是识别出http请求者的身份,除此之外尽量不要管其它的事.webapi的authentication我用authentica ...

  9. webapi框架搭建-安全机制(一)

    本系列博客链接:webapi框架搭建系列博客 前言 webapi接口是开放给外部使用的,包括接口的地址,传参的规范,还有返回结果的说明.正因为接口的开放性,使得接口的安全很重要.试想一下,用抓包工具( ...

随机推荐

  1. type=hidden

    非常值得注意的一个,通常称为隐藏域:如果一个非常重要的信息需要被提交到下一页,但又不能或者无法明示的时候. 一句话,你在页面中是看不到hidden在哪里.最有用的是hidden的值.

  2. Spring及Spring Boot 国内快速开发框架

    http://www.javacoder.top/home.jsp# http://springboot.fun/ 一个常用的支付子项目 https://gitee.com/52itstyle/spr ...

  3. Windows10下手工强制清理删掉安装版的JRE8导致java.exe无法运行的解决办法

    error:could not open xxxx.jvm.cfg 参考:https://blog.csdn.net/u010102493/article/details/18425267 1.搜索并 ...

  4. 用IntelliJ IDEA编译,编译之后提示 无效的标记: -release

    软件版本:ideaIU-2016.3.2 JDK:jdk-9.0.4_windows-x64_bin 开始的时候建立一个maven项目,发现编译的时候提示[无效的标记: -release],以为是项目 ...

  5. Java微信二次开发(七)

    自定义菜单 第一步:新建包com.wtz.menu,新建类Button.java package com.wtz.menu; /** * @author wangtianze QQ:864620012 ...

  6. Lodop设置打印维护返回打印语句代码

    打印设计关闭时,可以返回设计的打印代码,打印维护则返回成功打印的次数.不过打印维护也是返回打印程序代码的,方法就是加个语句,这个语句是: LODOP.SET_PRINT_MODE("PRIN ...

  7. ubuntu 程序后台运行几个方法

    51 1. 程序后加上“&” ,即 “./myjob &”, 将命令放入到一个作业队列中,可以用命令“jobs” 查看 2. 将1中的命令放在 “()”中, 即 “(./myjob & ...

  8. BZOJ4448[Scoi2015]情报传递——主席树+LCA

    题目描述 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头目外其余n-1名情报员有且仅有1名上线.奈特公司纪律森严 ...

  9. 睡前小dp-poj1276-多重背包+二进制优化

    http://poj.org/problem?id=1276 简单的多重背包,不过需要优化一下才能过.网上还有暴力的做法. 二进制优化在背包九讲里讲的比较清楚.对于多重背包的每一件物品,使用二进制的形 ...

  10. [ctsc2018] 混合果汁 【可持久化线段树】【二分答案】

    题目分析 首先考虑到最小值最大,二分答案.假设答案为k,显然这满足单调性.如果某个k使得这个情况下选不出.那么比k大的一定也选不出,所以二分答案. 接着我们可以贪心,当我们确认了k以后,一定会优先选费 ...