在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理。引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想,通过Filter能统一地对一些通用逻辑进行处理,如:权限校验、参数加解密、参数校验等方面我们都可以利用这一特性进行统一处理,今天我们来介绍Filter的开发、使用以及讨论他们的执行顺序。

一、Filter的使用

在默认的WebApi中,框架提供了三种Filter,他们的功能和运行条件如下表所示:

Filter 类型

实现的接口

描述

Authorization

IAuthorizationFilter

最先运行的Filter,被用作请求权限校验

Action

IActionFilter

在Action运行的前、后运行

Exception

IExceptionFilter

当异常发生的时候运行

1.授权拦截过滤器

首先,我们实现一个CustomAuthorizeAttribute可以用以简单的权限控制,(此处AuthorizeAttribute继承自AuthorizationFilterAttribute)用于接口授权:

/// <summary>
/// 自定义授权
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute:AuthorizeAttribute
{
/// <summary>
/// 用户授权
/// </summary>
/// <param name="actionContext"></param>
/// <returns></returns>
public override void OnAuthorization(HttpActionContext actionContext)
{
//url获取token
var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
HttpRequestBase request = content.Request;
string access_key = request.Params["access_key"];//不管是post请求还是get请求,都从地址栏获取key跟sign
string sign = request.Params["sign"];
//校验IP
var data=XmlUtil.IsAuthorization(HttpContext.Current.Request.UserHostAddress);
if (data.IsExistence)//ip是否在白名单内
{
if ("".Equals(data.IsAuthorization))//是否需要参与签名验证
{
if (!string.IsNullOrEmpty(access_key) && !string.IsNullOrEmpty(sign))
{
var key = "7058e63cdf0646948201";//随便固定一个key,真实使用的化可以从数据库获取或配置文件读取
var s = MD5Encrypt32(string.Format("{0}{1}", access_key, key));
if ("2c3a368b-26a8-4a4d-a204-14bd6388f3c2".Equals(access_key) && s.Equals(sign))//验证通过放行
{
base.IsAuthorized(actionContext);
}
else
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
code = HttpStatusCode.Unauthorized,
data = "",
message = "access_key 或 sign 参数有误,请核对",
});
}
}
else
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
code = HttpStatusCode.Unauthorized,
data = "",
message = "access_key 或 sign 校验参数未从地址栏带入,请核对",
});
}
}
else
{
base.IsAuthorized(actionContext);
}
}
else
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new
{
code = HttpStatusCode.Unauthorized,
data = "",
message = $"IP:{HttpContext.Current.Request.UserHostAddress}没有调用服务的权限",
});
}
}
/// <summary>
/// 32位MD5加密
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public string MD5Encrypt32(string password)
{
string pwd = "";
MD5 md5 = MD5.Create(); //实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = ; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
pwd = pwd + s[i].ToString("X");
}
return pwd.ToLower();
}
}

2.错误异常捕获过滤器

当服务端代码报错或出异常时,可自定义设置固定格式的异常返回给调用者,具体实现如下:

/// <summary>
/// 自定义错误异常捕获
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomExceptionAttribute:ExceptionFilterAttribute
{
/// <summary>
/// 异常发生
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
//记录错误日志
Task.Run(() =>
{
//此处可以调用记录日志方法
});
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError, new
{
code = HttpStatusCode.InternalServerError,
message = actionExecutedContext.Exception.Message
});
}
}

3.请求成功过滤器

如果要把所有接口返回类型参数固定可以使用ActionFilter过滤器,简单实现如下:

/// <summary>
/// 自定义统一信息格式返回
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomActionAttribute:ActionFilterAttribute
{
/// <summary>
/// 请求成功之后
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(actionExecutedContext.Response.StatusCode, new
{
code = ,
data =JsonConvert.DeserializeObject(actionExecutedContext.Response.Content.ReadAsStringAsync().Result),//返回给调用者的数据
message ="success"
});
}
}

接口调用成功之后返回给调用者的数据格式都是固定格式,调用者使用起来就很方便,返回固定格式如下:

{
code = ,
data ="数据"
message ="success"
}

二、过滤器的使用及注册

过滤器注册方式有三种:

  • 全局注册
  • 类注册
  • 方法注册

1.全局注册

全局注册时在App_Start==>WebApiConfig.cs文件里面,注册代码如下:

public static class WebApiConfig
{
/// <summary>
///
/// </summary>
/// <param name="config"></param>
public static void Register(HttpConfiguration config)
{
// 身份认证筛选器。
config.Filters.Add(new CustomAuthorizeAttribute());//这是全局注册 config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
); config.EnsureInitialized();
}
}

2.控制器注册

控制器注册就是在Controller类里面进行注册,注册代码如下:

/// <summary>
///
/// </summary>
[CustomAuthorizeAttribute] //控制器注册
public class DepartmentApiController : ApiController { }

3.方法注册

方法注册就是在Controller里面使用的方法上进行标记注册,注册代码如下:

/// <summary>
///
/// </summary>
public class DepartmentApiController : ApiController { [CustomAuthorizeAttribute]//方法注册
[HttpGet]
public object GetDepartmentList()
{ }
}

三、过滤器执行优先级

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = false)]//AllowMultiple=false时 执行优先级如下

同一个过滤器分别用在了全局、控制器和行为方法中,执行同一个方法时都会有先后顺序,如果按默认值(不设Order的情况下),一般的顺序是由最外层到最里层,就是“全局”——>“控制器”——>“行为方法”;

而特别的就是错误处理的过滤器,由于异常是由里往外抛的,所以它的顺序刚好也反过来:“行为方法”——>“控制器”——>“全局”。

以上是开发webapi过滤器的简单用法,以上代码还需要优化,有需要的朋友自己封装优化一下就可以使用了。

C# WebApi 过滤器的使用开发接口必备利器的更多相关文章

  1. C# WebApi过滤器(开发接口必备利器)

    在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...

  2. C/C++服务器开发的必备利器–libconfig

    http://www.leoox.com/?p=311 程序肯定需要一份配置文件,要不然,自己的程序不是“可配置”的,自己都不好意思往“高大上”靠拢.言归正传,以前自己写代码,配置文件的读写都是各式各 ...

  3. MVC WebAPI 三层分布式框架开发

    版权声明:本文为博主原创文章,未经博主允许不得转载. 前言:SOA(面向服务的架构)是目前企业应用开发过程中普遍采用的技术,基于MVC WebAPI三层分布式框架开发,以此适用于企业信息系统的业务处理 ...

  4. Web 开发人员必备的随机 JSON 数据生成工具

    在 Web 开发中,经常会需要一些测试数据来测试接口或者功能时候正确.JSON Generator 就是这样一款生成随机 JSON 数据的在线工具,Web 开发人员必备,记得收藏和分享啊. 您可能感兴 ...

  5. 转载CSDN (MVC WebAPI 三层分布式框架开发)

    前言:SOA(面向服务的架构)是目前企业应用开发过程中普遍采用的技术,基于MVC WebAPI三层分布式框架开发,以此适用于企业信息系统的业务处理,是本文论述的重点.此外,插件技术的应用,富客户端JQ ...

  6. Android开发学习必备的java知识

    Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...

  7. Fiddler无所不能——之测试开发攻城狮必备利器

    Fiddler无所不能——之测试开发攻城狮必备利器 1.模拟真实网络环境4g网.3g网络.2g网络.弱网.请求超时 开启弱网Rules——Performance——勾选Simulate Modem S ...

  8. (转载)Android快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup

    [置顶] [Android]快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup 标签: androidAdapter快速开发0耦合 2016-12-1 ...

  9. ASP.NET Core WebApi基于Redis实现Token接口安全认证

    一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebSer ...

随机推荐

  1. 纯php实现中秋博饼游戏(2):掷骰子并输出结果

    这篇是纯php实现中秋博饼游戏系列博文(2) 上文是:纯php实现中秋博饼游戏(1):绘制骰子图案 http://www.cnblogs.com/zqifa/p/php-dice-1.html要纯ph ...

  2. UOJ 54 【WC2014】时空穿梭——莫比乌斯反演

    题目:http://uoj.ac/problem/54 想写20分. Subtask 2 就是枚举4个维度的值的比例,可算对于一个比例有多少个值可以选,然后就是组合数.结果好像不对. 因为模数太小,组 ...

  3. VMware ESXi NAT实现

    VMware ESXi默认不支持NAT,但是我们如果只有一个外网端口映射,然后希望通过这个映射,从外网访问两台机器的话,那最好做NAT.这里我们通过一个开源的网络防火墙pfSense来实现NAT[1] ...

  4. 字符串循环右移N位

    给一个长度为n的字符串,把这个字符串循环右移N位(0<N<n),要求只用O(1)的额外空间和O(N)时间,有些什么方法 一开始想到的是先保存temp=s[0],在左起第N个移到s[0]的位 ...

  5. [DP题]采药

    1775:采药 总时间限制:1000ms内存限制:65536kB 描述 辰辰是个很有潜能.天资聪颖的孩子,他的梦想是称为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给 ...

  6. 【并发编程】Executor架构介绍

    要点总结 Executor表示的任务类型 主要有3种: Runnable: 无返回值,无异常抛出: Callable:有返回值,可以异常抛出: Future任务: 表示异步计算,可取消: 通过newT ...

  7. Entity Framework的优势和缺点

    优点:简单说就是Entity Framework省事,做业务系统,管理系统会减少很多代码,程序员可以更关注业务实现本身. 缺点:当处理大数据量和高并发时,由于Entity Framework是自动化程 ...

  8. uwsgi的python2+3多版本共存实操使用virtualenv

    1首先,机器需要有python2和python3的可执行环境.确保pip和pip3命令可用.原理就是在哪个环境下安装uwsgi.uwsgi启动的时候,就用的哪个python版本 2安装virtuale ...

  9. Python实践练习:正则表达式查找

    题目 编写一个程序,打开文件夹中所有的.txt 文件,查找匹配用户提供的正则表达式的所有行.结果应该打印到屏幕上. 代码 #!/usr/bin/python # -*- coding: UTF-8 - ...

  10. windows下使用 ApiGen 生成php项目的开发文档

    之前使用 PHPDocument 生成过开发文档,但是界面看着不爽,遂尝试了 ApiGen 生成,不得不说界面看着舒服多了,下面说说安装和使用的方法. ApiGen官网: http://www.api ...