拦截器又称过滤器。

asp.net mvc本身是自带3种拦截器:Action拦截器、Result拦截器、Exception拦截器。 应用中常见的拦截器有日志拦截器(Action拦截器)和异常处理拦截器(Exception拦截器)。

java里spring mvc也常用拦截器来做些非干预业务逻辑的事,诸如实现HandlerInterceptor接口。

拦截器是AOP(面向切面编程)的一种应用。

拦截器要解决的问题:

1.代码复用。拦截器可被复用
2.职责单一。比如厨师只负责炒菜,不管前期的洗菜、后续的送菜工作。菜变质了也是直接喊一声就有人来处理。
 
asp.net的拦截器怎么实现呢?
旧瓶装新酒,asp.net的拦截器需要通过IHttpModule接口来实现。
 

这两天重构支付中心代码,将设置线程名和IP白名单这2个功能做成拦截器。
 
如下是线程名Filter的代码:
    /// <summary>
/// 设置当前工作线程的名称。供用来统一标识记录的日志
/// </summary>
public class ThreadNameFilter : IHttpModule
{
LogHelperUtil logHelper = new LogHelperUtil(typeof(ThreadNameFilter).Name); public void Dispose()
{
//throw new NotImplementedException();
} public void Init(HttpApplication context)
{
//NewMethod(context);请求在此上下文中不可用 context.BeginRequest += context_BeginRequest;
} /// <summary>
/// 设置当前工作线程的name
/// </summary>
/// <param name="sender"></param>
private void SetThreadName(object sender)
{ if (null != Thread.CurrentThread.Name)
{
return;
} HttpApplication application = (HttpApplication)sender;
HttpRequest request2 = application.Context.Request;
HttpResponse response = application.Context.Response;
string url = request2.Url.LocalPath;
url = url.Trim('/'); // * 根据请求url得到一个nameFlag
string nameFlag;
if (url.IndexOf(".ashx", StringComparison.OrdinalIgnoreCase) > )
{
var arr = url.Split('/');
string ashxName = arr.FirstOrDefault(str => str.IndexOf(".ashx", StringComparison.OrdinalIgnoreCase) > );
nameFlag = ashxName.Substring(, ashxName.IndexOf('.'));
if (nameFlag == "AgentPayQuery")
{
nameFlag = "QueryAgentPay";
}
}
else
{
nameFlag = url.Replace('/', '_').Replace('.', '_');
} // * 设置当前工作线程的name
Thread.CurrentThread.Name = string.Format("[{0}_T{1:HHmmssfff}_{2}]", nameFlag, DateTime.Now, Guid.NewGuid().ToString().Replace("-", "").Substring(, ).ToUpper());
logHelper.Write("线程名已设置为:{0} url:{1}", Thread.CurrentThread.Name, url);
} void context_BeginRequest(object sender, EventArgs e)
{
SetThreadName(sender);
} }

接下来,web.config配置此module:

可在<system.web>节点下的<httpModules>里配置,也可在<system.webServer>节点下的<modules>里配置。  这取决于应用程序池的托管管道模式。经典模式用前者,集成模式用后者。

本地vs2013里的iisexpress默认是集成模式。所以,本地vs2013调试程序要在<system.webServer>里配置module。

  <system.webServer>
<modules> <!--runAllManagedModulesForAllRequests="true"-->
<add name="threadNameFilter" type="PaymentPlatform.Filters.ThreadNameFilter" preCondition="managedHandler" />
<add name="ipValidationInterceptor" type="PaymentPlatform.Filters.IPValidationInterceptor" preCondition="managedHandler"/> <!--只对托管资源起作用-->
</modules>
<handlers>
。。。。。。
</handlers>
</system.webServer>

这样,一个拦截器的开发就完成了。

在后续的测试时,出现了一些波折。

本地在启动vs2013执行iisexpress站点应用程序时,发现明明在ThreadNameFilter 里设置了线程名,但观察在后续ashx里记录的日志里,并没有获取到那个线程名,whatever in Debug or in Release。这让我想到之前写的一篇博客《巧用CurrentThread.Name来统一标识日志记录(续)》,在ashx文件的默认构造器里设置的线程名,在其ProcessRequest方法的处理逻辑里也是获取不到的。

经多次鼓捣,才发现,把站点程序发布到IIS7上之后,无论apppool的托管模式是集成(目前,集成模式是主流)还是经典,在ThreadNameFilter 里设置的线程名可以被后续ashx里获取到!

同样,细心的观察了一下,《巧用CurrentThread.Name来统一标识日志记录(续)》里提到的问题,发布到IIS7后也不存在,即在ashx文件的默认构造器里设置的线程名,在其ProcessRequest方法的处理逻辑里可以获取到!

下图是本地vs2013里访问接口所记录的日志:

下图是发布到iis7后访问接口所记录的日志:

asp.net拦截器的更多相关文章

  1. Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码

    本问主要介绍asp.net的身份验证机制及asp.net MVC拦截器在项目中的运用.现在让我们来模拟一个简单的流程:用户登录>权限验证>异常处理 1.用户登录 验证用户是否登录成功步骤直 ...

  2. ASP.NET MVC 拦截器IResultFilter

    在ASP.NET MVC中,有一个Result拦截器,实现ResultFilter需要继承一个类(System.Web.Mvc.FilterAttribute)和实现一个类(System.Web.Mv ...

  3. ASP.NET MVC 异常Exception拦截器Fillter

    异常信息的处理在程序中非常重要, 在asp.net mvc中提供异常属性拦截器进行对异常信息的处理,异常拦截器也没有什么的,只是写一个类,继承另一个类(System.Web.Mvc.FilterAtt ...

  4. ASP.NET MVC案例——————拦截器

    摘要      本文将对“MVC公告发布系统”的发布公告功能添加日志功能和异常处理功能,借此来讨论ASP.NET MVC中拦截器的使用方法. 一个小难题      我们继续完善“MVC公告发布系统”, ...

  5. ASP.NET MVC中的拦截器

    在ASP.NET MVC中,有三种拦截器:Action拦截器.Result拦截器和Exception拦截器, 所谓的拦截器也没有什么的,只是写一个类,继承另一个类和一个接口,顺便实现接口里面的方法而以 ...

  6. 在ASP.NET Core MVC中子类Controller拦截器要先于父类Controller拦截器执行

    我们知道在ASP.NET Core MVC中Controller上的Filter拦截器是有执行顺序的,那么如果我们在有继承关系的两个Controller类上,声明同一种类型的Filter拦截器,那么是 ...

  7. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第六篇:拦截器

    摘要      本文将对“MVC公告发布系统”的发布公告功能添加日志功能和异常处理功能,借此来讨论ASP.NET MVC中拦截器的使用方法. 一个小难题      我们继续完善“MVC公告发布系统”, ...

  8. ASP.NET Core 3.0 gRPC 拦截器

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 拦截器 一. 前言 前面两篇文章给大家介绍了使用g ...

  9. ASP.NET Core搭建多层网站架构【9.2-使用Castle.Core实现动态代理拦截器】

    2020/01/31, ASP.NET Core 3.1, VS2019, Autofac.Extras.DynamicProxy 4.5.0, Castle.Core.AsyncIntercepto ...

随机推荐

  1. [No0000178]改善C#程序的建议1:非用ICloneable不可的理由

    好吧,我承认,这是一个反标题,实际的情况是:我找不到一个非用ICloneable不可的理由.事实上,接口ICloneable还会带来误解,因为它只有一个Clone方法. 我们都知道,对象的拷贝分为:浅 ...

  2. 多线程 ForkJoinPool

    阅读目录 使用 背景:ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成 ...

  3. HQL之动态分区调整

    动态分区插入可以基于查询语句分出出要插入的分区名称.比如,下面向分区表插入数据的SQL: insert into table chavin.emp_pat partition(dname,loc) s ...

  4. ASP.NET MVC 计划任务(不使用外接程序,.net内部机制实现)

    在asp.net中要不使用其他插件的情况下只能使用定时器来检查, 并执行任务. 以下讲解步骤: 1. 在Global.asax 文件中作如下修改 1 2 3 4 5 6 7 8 9 10 11 voi ...

  5. AngularJS 常用的功能

    第一 迭代输出之ng-repeat标签ng-repeat让table ul ol等标签和js里的数组完美结合 例: <ul><li ng-repeat="person in ...

  6. In abstract algebra, a congruence relation (or simply congruence) is an equivalence relation on an algebraic structure (such as a group, ring, or vector space) that is compatible with the structure in

    https://en.wikipedia.org/wiki/Congruence_relation In abstract algebra, a congruence relation (or sim ...

  7. iOS自定义结构体

    一.提要 通过以官方的CGSize为例,自定义Objective-C中的结构体,并使用. 二.CGSize 1.系统定义的CGSize结构体 struct CGSize { CGFloat width ...

  8. java中组合与聚合(聚集)的区别

    组合和聚合是有很大区别的,这个区别不是在形式上,而是在本质上:  组合:比如A类中包含B类的一个引用b,当A类的一个对象消亡时,b这个引用所指向的对象也同时消亡(没有任何一个引用指向它,成了垃圾对象) ...

  9. PHP进阶-网络编程基础概念

    以太网协议图: 以太网协议: 发送header(发送至mac地址,接收者mac地址).data到网线中所有连接的计算机,然后每个机子接收数据包的时候都是用以太网协议的, 然后解析header头,看是否 ...

  10. [CentOS7][ssh][publickey][troubleshoot] 通过密钥登录ssh故障排查

    通常情况下,我会使用非对称加密的方式来进行ssh的登录. 做法: 将公钥添加到 $HOME/.ssh/authorized_keys 文件中. 但是通常,会遇见各种各样的问题,导致失败.汇总如下: 0 ...