欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mvc动态注册HttpModule详解

程序员文章站 2023-11-21 21:49:34
序言 注册httpmodule可以让我们使用httpapplication对象中的处理管道事件。目前大家所熟知的应该有2种方式来使用httpapplication对象中的...

序言

注册httpmodule可以让我们使用httpapplication对象中的处理管道事件。目前大家所熟知的应该有2种方式来使用httpapplication对象中的处理管道事件。第一种是通过global.asax全局文件,另外一种是通过配置文件来注册httpmodule。那么有这2种方式啦,为什么还要有今天这篇博客呢?

这里我也提1个简单的问题,用实例来证明下动态注册httpmodule的可取之处。

如果你要写一个.net框架,供公司所有mvc项目使用,那么你的框架集成的众多功能中,至少应该需要一个异常记录的功能吧,有啦这个功能之后,别人的项目即便忘记处理异常信息,那么框架也会帮忙一个不拉的将项目异常信息写入框架的日志当中,还有你的框架要叼,怎么叼呢?叼到别人不需要写如一行代码即可实现这样的功能,哇咔,怎么实现?在你的框架中,只需要几行代码即可。

microsoft.web.infrastructure.dll与preapplicationstartmethodattribute属性

首先我们利用ilspy来看下microsoft.web.infrastructure.dll这个类库是干什么的,如图:

 Mvc动态注册HttpModule详解

[securitysafecritical]
public static void registermodule(type moduletype)
{
  if (dynamicmodulereflectionutil.fx45registermoduledelegate != null)
  {
dynamicmodulereflectionutil.fx45registermoduledelegate(moduletype);
    return;
  }dynamicmoduleutility.legacymoduleregistrar.registermodule(moduletype);
}

那看到此类库的源码之后,便可以顺藤摸瓜,看清其真面目啦。

  1. microsoft.web.infrastructure.dynamicmodulehelper 此命名空间我们可以看出他是关于动态module的helper 。
  2. dynamicmoduleutility此类便是实用类,那么打开之后,便看到啦一个醒目的方法,registermodule,注册module,没错他就是动态注册httomodule的方法。

思考一下上面我的命题,是在项目中一行代码不用便可执行我们的类库,那么动态注册httpmodule有啦,接下来就是怎么一行代码不写,就能运行我们的类库呢?这就用到啦微软提供的preapplicationstartmethodattribute 属性。

  1. preapplicationstartmethodattribute:此属性也可以望文生义,便是在application启动之前要运行的方法。就是说他也是一个程序的入口点,并且还是application初始化之前便启动啦,万物之初先有的便是它,造作吧。
  2. webactivatorex:这是一个类库,微软提供啦preapplicationstartmethodattribute特性,微软nuget开发小组有一个成员david ebbo写啦这个更叼的类库,内容如下图

Mvc动态注册HttpModule详解

呢,这个类库可以动态注册httpmoudle,他还实现不修改全局文件就可以加入,application_start()/shutdown()事件,源码你可以使用ilspy查看,也有项目的git地址,通过nuget可以获取,值得你去研究下。

Mvc动态注册HttpModule详解

代码实现动态注册httpmoudle

[assembly: webactivatorex.preapplicationstartmethod(typeof(routingcore.preapplicationstartregist), "prestart")]
namespace routingcore
{
  public class preapplicationstartregist
  {
    private static bool hasloaded;
    public static void prestart()
    {
      if (!hasloaded)
      {
        hasloaded = true;
        dynamicmoduleutility.registermodule(typeof(routingmodule));
      }
    }
  }
}
public class routingmodule : ihttpmodule
  {
    public void init(httpapplication context)
    {
      context.beginrequest += new eventhandler(context_beginrequest);
      context.error += new eventhandler(context_errorrequest);
    }
    void context_beginrequest(object sender, eventargs e)
    {
    }
    void context_errorrequest(object sender, eventargs e)
    {
      httpapplication ap = sender as httpapplication;
      var error = ap.server.getlasterror();
      var code = (error is httpexception) ? (error as httpexception).gethttpcode() : 500;
      if (code != 404)
      {
      }
      // 写入本地文件,队列或数据库 
      // ...          
      ap.server.clearerror();
      ap.response.write(error.message);
      ap.response.end();
    }
    public void dispose() { }
  }

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!