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. PAT 1016 部分A+B

    https://pintia.cn/problem-sets/994805260223102976/problems/994805306310115328 正整数A的“D~A~(为1位整数)部分”定义 ...

  2. HDU 2052 Picture

    http://acm.hdu.edu.cn/showproblem.php?pid=2052 Problem Description Give you the width and height of ...

  3. 一种快速统计SQL Server每个表行数的方法

    转载自:http://www.cnblogs.com/kenyang/archive/2013/04/09/3011447.html 我们都知道用聚合函数count()可以统计表的行数.如果需要统计数 ...

  4. Oracle 数据库启动过程

    一 启动数据库 Oracle启动过程涉及几种模式,这些模式涉及不同的文件,每个状态下数据库做不同的事情,同时这些模式适用于不同的维护需求,主要的模式有三种:NOMOUNT.MOUNT.OPEN. 1 ...

  5. 软件工程_10th weeks

    不管是什么原因,都没有在周三24:00前发布博客,赶紧用行动补上~ psp DATE START_TIME END_TIME EVENT TYPE     DELTA 5.8 9:00 12:00 论 ...

  6. hive web界面管理

    老版本使用 访问<Hive Server Address>:9999/hwi 1.首先下载对应版本的src文件,本机使用apache-hive-1.2.2-src.tar.gz 2.解压缩 ...

  7. HTML5 & auto download image

    HTML5 & auto download image https://www.sitepoint.com/new-html5-attributes-hyperlinks-download-m ...

  8. QAU 17校赛 J题 剪丝带(完全背包变形)

    题意: 剪一段丝带,对于剪完后的每一段丝带长度必须是a,b,c 输入丝带的长度  n 和  a  b  c 输出一个整数,代表最多能剪成多少段 样例输入 5 5 3 2 7 5 5 2 样例输出 2 ...

  9. Threed.sleep是不会释放锁,而wait是释放锁的(对象锁)

    实战分析 一直都说,Threed.sleep是不会释放锁,而wait是释放锁的(对象锁),现理论上来分析一下啊. v package thread.concurrent; public class D ...

  10. 自学Linux Shell12.7-控制循环break、continue命令

    点击返回 自学Linux命令行与Shell脚本之路 12.7-控制循环break.continue命令 break命令.break命令用于跳出循环,使用break可以跳出任何类型的循环:for.whi ...