C# WebApi过滤器(开发接口必备利器)
在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理。引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想,通过Filter能统一地对一些通用逻辑进行处理,如:权限校验、参数加解密、参数校验等方面我们都可以利用这一特性进行统一处理,今天我们来介绍Filter的开发、使用以及讨论他们的执行顺序。
一、Filter的开发和调用
在默认的WebApi中,框架提供了三种Filter,他们的功能和运行条件如下表所示:
Filter 类型 |
实现的接口 |
描述 |
Authorization |
IAuthorizationFilter |
最先运行的Filter,被用作请求权限校验 |
Action |
IActionFilter |
在Action运行的前、后运行 |
Exception |
IExceptionFilter |
当异常发生的时候运行 |
首先,我们实现一个AuthFilterOutside可以用以简单的权限控制:
public class AuthFilterOutside: AuthorizeAttribute
{
private SP_PortUserBLL sp_portuserbll = new SP_PortUserBLL();
//重写基类的验证方式,加入我们自定义的Ticket验证
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.Form["access_key"];//获取请求参数对应的值
string sign = request.Form["sign"];
if (!string.IsNullOrEmpty(access_key) && !string.IsNullOrEmpty(sign))
{
//解密用户ticket,并校验用户名密码是否匹配
if (ValidateTicket(access_key, sign))
{
base.IsAuthorized(actionContext);
}
else
{
HandleUnauthorizedRequest(actionContext);
}
}
//如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
else
{
var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
if (isAnonymous) base.OnAuthorization(actionContext);
else HandleUnauthorizedRequest(actionContext);
}
}
//校验sign(数据库数据匹配)
private bool ValidateTicket(string key,string sign)
{
var result=sp_portuserbll.GetAccess_secret(key);
if (!string.IsNullOrEmpty(result))
{
var mysing= Encryption.DataEncryption(key, result);//sign验证
if (mysing.Equals(sign))
{
return true;
}
return false;
}
return false;
}
}
当请求地址里面包含 access_key 和 sign 对应的键值对,获取对应的值与数据库数据进行匹配,匹配通过后可请求数据,适用于get 、post请求。
接口请求成功后记录日志的实现
/// <summary>
/// 请求成功后触发
/// </summary>
public class AuthFilter: ActionFilterAttribute
{
private PortLogBLL portlogbll = new PortLogBLL();
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
//action 请求之后触发<br> //日志记录 访问量记录等等
portlogbll.SaveForm(new PortLogEntity()
{
PortName = actionExecutedContext.Request.RequestUri.AbsolutePath,//获得调用接口,
RequestType = actionExecutedContext.Request.Method.ToString(),
StatusCode = Convert.ToInt32(new HttpResponseMessage(HttpStatusCode.OK).StatusCode),//设置状态码
ClientIp = GetClientIp(),
ParameterList = actionExecutedContext.ActionContext.ActionArguments.ToJson(),//获得参数值
Success = true
});
}
/// <summary>
/// 获取客户端Ip
/// </summary>
/// <returns></returns>
private string GetClientIp()
{
string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(result))
{
result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
if (string.IsNullOrEmpty(result))
{
result = HttpContext.Current.Request.UserHostAddress;
}
if (string.IsNullOrEmpty(result))
{
return "0.0.0.0";
}
return result;
}
}
当服务端代码报错或出异常时,可自定义设置固定格式的异常返回给调用者
/// <summary>
/// 接口发生异常过滤器
/// </summary>
public class ExceptionHandling : ExceptionFilterAttribute, IExceptionFilter
{
private PortLogBLL portlogbll = new PortLogBLL();
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var code = new HttpResponseMessage(HttpStatusCode.InternalServerError).StatusCode;//设置错误代码:例如:500 404
actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
string msg = JsonConvert.SerializeObject(new BaseResult() { success = false, message = actionExecutedContext.Exception.Message });//返回异常错误提示
//写入错误日志相关实现
portlogbll.SaveForm(new PortLogEntity()
{
PortName = actionExecutedContext.Request.RequestUri.AbsolutePath,
RequestType = actionExecutedContext.Request.Method.ToString(),
StatusCode = Convert.ToInt32(code),
ClientIp = GetClientIp(),
ParameterList = actionExecutedContext.ActionContext.ActionArguments.ToJson(),
Success = false,
ErrorMessage = msg
});
//result
actionExecutedContext.Response.Content = new StringContent(msg, Encoding.UTF8);
}
/// <summary>
/// 获取调用接口者ip地址
/// </summary>
/// <returns></returns>
private string GetClientIp()
{
string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(result))
{
result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
if (string.IsNullOrEmpty(result))
{
result = HttpContext.Current.Request.UserHostAddress;
}
if (string.IsNullOrEmpty(result))
{
return "0.0.0.0";
}
return result;
}
}
public class BaseResult
{
/// <summary>
/// 状态
/// </summary>
public bool success { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public string message { get; set; }
}
以上是开发webapi常用代码,自己封装一下就可以使用了
C# WebApi过滤器(开发接口必备利器)的更多相关文章
- C# WebApi 过滤器的使用开发接口必备利器
在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...
- C/C++服务器开发的必备利器–libconfig
http://www.leoox.com/?p=311 程序肯定需要一份配置文件,要不然,自己的程序不是“可配置”的,自己都不好意思往“高大上”靠拢.言归正传,以前自己写代码,配置文件的读写都是各式各 ...
- Fiddler无所不能——之测试开发攻城狮必备利器
Fiddler无所不能——之测试开发攻城狮必备利器 1.模拟真实网络环境4g网.3g网络.2g网络.弱网.请求超时 开启弱网Rules——Performance——勾选Simulate Modem S ...
- (转)Terraform,自动化配置与编排必备利器
本文来自作者 QingCloud实践课堂 在 GitChat 上分享 「Terraform,自动化配置与编排必备利器」 Terraform - Infrastructure as Code 什么是 T ...
- Web 开发人员必备的随机 JSON 数据生成工具
在 Web 开发中,经常会需要一些测试数据来测试接口或者功能时候正确.JSON Generator 就是这样一款生成随机 JSON 数据的在线工具,Web 开发人员必备,记得收藏和分享啊. 您可能感兴 ...
- Android开发工具综述,开发人员必备工具
安卓开发工具汇总.开发者必备.安卓开发过程中须要用到各种工具,作为一名安卓开发者,有木有感到亚历山大,那么多工具! 今天给大家汇总了一下安卓开发工具,安卓开发者必备利器. 1.Draw 9-Patch ...
- QuickWebApi2:使用Lambda方式,完成对WebApi的开发和调用-文档的生成
续 QuickWebApi:使用Lambda方式,完成对WebApi的开发和调用 上一篇完成了主要的功能,本次修订主要重构了对接口文档的生成规范,使之可读性更佳,甚至可以作为接口文档进行发布(当然,在 ...
- QuickWebApi:使用Lambada方式,完成对WebApi的开发和调用。
QuickWebApi 目的:使用Lambada方式,完成对WebApi的开发和调用. 缘由:为了解耦服务和展现,将越来越多的使用WebApi提供各种服务:随着服务的细化,WebApi的接口将越来越多 ...
- Android开发学习必备的java知识
Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...
随机推荐
- Thread的其他属性方法
from threading import Thread,currentThread,active_count import time def task(): print('%s is running ...
- linux常用命令(个人总结)
1.快捷键: ctrl + l --------------------清屏 ctrl + c --------------------退出当前命令 ctrl + ...
- 数据库 -- mysql表操作
一,存储引擎介绍 存储引擎即表类型,mysql根据不同的表类型会有不同的处理机制 详见:https://www.cnblogs.com/peng104/p/9751738.html 二,表介绍 表相当 ...
- 洛谷P1897电梯里的爱情题解
题目 这个题是一个搜索题,可以先算出最高楼层,并算出不重复的楼层的个数,要注意的一点就是一定不要把0楼算在内. 代码 #include<iostream> #include<cstr ...
- CCF WC2017 & THU WC2017 旅游记
day-x 真·旅游 去了杭州的一些景点,打了几场练习赛. day0 报到日 领资料.入住,中午在食堂吃饭,感觉做的挺好的,和二高食堂差不多.晚上还有开幕式. day1~day4 白天讲课,晚上营员交 ...
- Java实现一个双向链表的倒置功能
题目要求:Java实现一个双向链表的倒置功能(1->2->3 变成 3->2->1) 提交:代码.测试用例,希望可以写成一个Java小项目,可以看到单元测试部分 该题目的代码, ...
- 【支付宝】支付 系统繁忙,请稍后再试(ALIN10146)
https://openclub.alipay.com/read.php?tid=6918&fid=60 我碰到的是这个问题导致 把signType 改为 RSA2 改成
- zabbix agent 自定义 UserParameter
有时候我们想让被监控端执行一个zabbix没有预定义的检测,zabbix的用户自定义参数功能提供了这个方法.我们可以在客户端配置文件zabbix_angentd.conf里面配置UserParamet ...
- 树莓派播放网络磁盘MP3文件
树莓派映射网络磁盘 sudo mount -t cifs -o username=jerry.huang,password=Hello2014 //10.10.0.1/Public/ESLPod.co ...
- 让自己的网站实现在线编辑office文档
我们可以通过Office Web Apps(OWA)来实现在线编辑word,excel,power point, one note,并集成到自己的网站里去. 1 准备工作 1.1 操作系统 安装了 ...