• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#自定义HttpFilter模块完善实例

C#自定义HttpFilter模块完善实例

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c#filter,c#中filter,httpfilter,httpfilter服务,没有httpfilter等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例讲述了C#自定义HttpFilter模块完善的方法,分享给大家供大家参考。具体实现方法如下:

一、背景

近期由于要针对项目做用户操作日志,但不想在每个方法里去增加代码,写入用户日志。因为这样具体的方法违背职责单一的原则,若后期日志内容格式发生变更,或其他什么需求,该方法代码主要一变在变,故使用HttpModule模块来完成此功能,感兴趣的朋友可以参考:关于HttpHandler与HttpModule的理解和应用方法

经过实际运用与完善,现在可以再次总结下。

二、拦截时机

现在的版本中,拦截的依据是,在每次请求发生的过程中,拦截控制器类请求,重定向http输出流,并分析出Controller与Action,接下来查找是否有方法监控了此控制器,若有,则分析出请求输入参数,与此次请求输出内容,存储在FilterContext中,交给该方法,完成相应逻辑。

由于在最初的写法中,是针对所有的请求进行流的重定向,在asmx下,会遇到问题,只要重定向了,调用服务的客户端会提示400 Http Bad Request 。这个具体的错误原因,还不清楚,但正是由于该错误,让我发现,我之前拦截的时机是错误的,理应放在请求之前,判断是否满足拦截的规则,若满足,则重定向输出流。

三、读取用户名

在Module模块中总会出点问题,最后使用了Cookie记住用户名,并直接定义为FilterContext一个属性。解释下这样做的原因:由于记住用户名的方式有很多,如Session、Cookie,即读取用户名的方式是可变的,所以尽可能将变化的内容在前面解决,这样监听控制器的方法,直接根据该属性获取用户名,否则用户名的读取时机,放在每个监听控制器模块之后,读取方式一旦发生变更,所有的模块都要改变,当然也可以通过继承一个base类来避免这么大的改变。

在这里我想表达的意思是:我们做类似底层库的东西,尽可能稳定,将变化点集中在库本身,这样依赖该库的应用才能稳定。若.net版本更新过程中,API都不稳定,想必我们也不会在去使用它。

四、应用之写入日志

典型例子如下:

public void Login(FilterContext context)
{
    //解析输出内容,这里针对要监听的控制器和方法来写的
    var arr = context.OutputBody.Split('|');
    var log = string.Format("userName:{0} password:{1}",arr);
    FilterLog.Log.Info(log);
}</div>

该方法表达的意思是,监控LoginController的Login方法。由于我们需要分析请求输出结果,所以分析的规则,与控制器是强依赖的,控制器的方法是怎么返回数据的,我们此处就要根据规则解析。我在项目中使用的是Json,所以监控的地方都需要Json的反序列化,这里仅仅是一个Demo。

另外一个方法可以监听一个控制器下的多个方法,或者多个控制器。这样是旨在解决有很多Action,输入参数和输出参数都是相同的,可能由于业务不同,仅仅在方法名和内部实现中有不同。

五、应用之更新缓存

首先关于Cache的应用,可以读下此文章,Asp.Net Cache高级用法。

由于此处我没有写例子,先描述我在项目中运用的情况。系统有很多数据字典,在请求该数据字典时,程序首先从数据库加载字典数据,并放入缓存,此时放入缓存有个技巧,设置过期时间,并设置移除缓存前的回调,我们来看看具体的方法定义:

// 摘要:
//     将对象与依赖项、到期策略以及可用于在从缓存中移除项之前通知应用程序的委托一起插入到 System.Web.Caching.Cache 对象中。
//
// 参数:
//   key:
//     用于引用对象的缓存键。
//
//   value:
//     要插入到缓存中的对象。
//
//   dependencies:
//     该项的文件依赖项或缓存键依赖项。当任何依赖项更改时,该对象即无效,并从缓存中移除。如果没有依赖项,则此参数包含 null。
//
//   absoluteExpiration:
//     所插入对象将到期并被从缓存中移除的时间。要避免可能的本地时间问题(例如从标准时间改为夏时制),请使用 System.DateTime.UtcNow
//     而不是 System.DateTime.Now 作为此参数值。如果使用绝对到期,则 slidingExpiration 参数必须设置为 System.Web.Caching.Cache.NoSlidingExpiration。
//
//   slidingExpiration:
//     缓存对象的上次访问时间和对象的到期时间之间的时间间隔。如果该值等效于 20 分钟,则对象在最后一次被访问 20 分钟之后将到期并被从缓存中移除。如果使用可调到期,则
//     absoluteExpiration 参数必须设置为 System.Web.Caching.Cache.NoAbsoluteExpiration。
//
//   onUpdateCallback:
//     从缓存中移除对象之前将调用的委托。可以使用它来更新缓存项并确保缓存项不会从缓存中移除。
//
// 异常:
//   System.ArgumentNullException:
//     key、value 或 onUpdateCallback 参数为 null。
//
//   System.ArgumentOutOfRangeException:
//     将 slidingExpiration 参数设置为小于 TimeSpan.Zero 或大于一年的等效值。
//
//   System.ArgumentException:
//     为要添加到 Cache 中的项设置 absoluteExpiration 和 slidingExpiration 参数。- 或 -dependencies
//     参数为 null,absoluteExpiration 参数设置为 System.Web.Caching.Cache.NoAbsoluteExpiration
//     并且 slidingExpiration 参数设置为 System.Web.Caching.Cache.NoSlidingExpiration。
public void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemUpdateCallback onUpdateCallback);</div>

仔细看看onUpdateCallback参数的描述:从缓存中移除对象之前将调用的委托。可以使用它来更新缓存项并确保缓存项不会从缓存中移除。

我在把数据字典放入缓存的同时传递读取缓存的委托,这样在主动移除缓存或者缓存过期时都将再次调用此委托,将数据字典再次放入缓存。所以一旦数据字典发生了变更,如增删改,那么就主动将字典缓存移除,它就可以自动更新过来,是不是很方便呢。

区别于写操作日志,不过是处理逻辑发生了变化,他们都需要请求的输入和输出。

六、其他

1.由于使用HttpModule来完成此功能,如需正常运行,需要在WebConfig中注册该模块。详见Demo。

2.项目中使用了Log4Net记录文本日志,并可以根据功能分类。详见:Log4Net日志分类维护。

完整实例代码点击此处本站下载。

希望本文所述对大家的C#程序设计有所帮助。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#自定义HttpFilter模块完善实例

相关文章

  • 2017-05-28C#中float的取值范围和精度分析
  • 2017-05-28C#二叉搜索树插入算法实例分析
  • 2017-05-28C#实现把指定数据写入串口
  • 2017-05-28C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?
  • 2017-05-28DevExpress之ChartControl创建Drill-Down样式的Title实例
  • 2017-05-28基于为何我不喜欢用Path.Combine的详解
  • 2017-05-28c#闭包使用方法示例
  • 2017-05-28理解C#中参数的值和引用以及传递结构和类引用的区别
  • 2017-05-28C#实现判断一个时间点是否位于给定时间区间的方法
  • 2017-05-28winform 使用Anchor属性进行界面布局的方法详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C# 解析 Excel 并且生成 Csv 文件代码分析
    • C#实现json的序列化和反序列化实例代码
    • Winform中Treeview实现按需加载的方法
    • C#实现的简单验证码识别实例
    • 如何应用C#实现UDP的分包组包
    • c# split分隔字符串使用方法
    • C#操作windows注册表的方法
    • c#方法中调用参数的值传递方式和引用传递方式以及ref与out的区别深入解析
    • 详解C#中的泛型以及编程中使用泛型的优点
    • 深入解析C#编程中泛型委托的使用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有