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作为一门语言,必然有他的语法规则.学习编程语 ...
随机推荐
- WebStorm开发React项目,修代码之后运行的项目不更新
昨天遇到一个恶心的问题,我新建了一个React.js项目,想做一点关于Pc端的开发,习惯性的用了WebStorm,可是发现一个问题,就是代码修改之后,浏览器上根本不会刷新.然后,我把方向定位在没有正确 ...
- codeforces467C
George and Job CodeForces - 467C The new ITone 6 has been released recently and George got really ke ...
- ie11的版本判断
我的电脑昨天更新的时候把ie11给更新出来了,然后发现我的skylineweb项目提示我的浏览器不是ie,这样显然是浏览器检测出现了问题.查找后找到了下面的解决方法.大家的电脑如果也更新成了ie11的 ...
- eclipse添加tomcat服务器
在网上找资料好辛苦,还不对,自己试了好久,终于成功了 还是一如既往的分享 右键 弄好以后发现如此简单| _ |
- ContOS 常用命令
文件与目录操作 命令 解析 cd /home 进入 ‘/home’ 目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd - 返回上次所在目录 cp file1 file2 将fi ...
- 「POJ3311」Hie with the Pie
题目链接 >http://poj.org/problem?id=3311< 题意:从0出发,经过所有点(点可以重复走)后回到0点,问最短路 思路分析: 这题和普通的最短路不太一样,因为题目 ...
- codeforces 997C.Sky Full of Stars
题目链接:codeforces 997C.Sky Full of Stars 一道很简单(?)的推式子题 直接求显然不现实,我们考虑容斥 记\(f(i,j)\)为该方阵中至少有\(i\)行和\(j\) ...
- 【HDU - 4342】History repeat itself(数学)
BUPT2017 wintertraining(15) #8C 题意 求第n(n<2^32)个非完全平方数m,以及\(\sum_{i=1}^m{\lfloor\sqrt i\rfloor}\) ...
- python学习日记(文件操作)
文件操作概述 计算机系统分为:操作系统,计算机硬件,应用程序. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序 ...
- JavaWeb架构发展
原文:JavaWeb项目为什么我们要放弃jsp?为什么要前后端解耦?为什么要前后端分离?2.0版,为分布式架构打基础 前戏 前后端分离已成为互联网项目开发的业界标准使用方式,通过Nginx + Tom ...