ASP.NET MVC Module
在asp.net中管道模型是怎么来实现的?在请求处理流程一文中大概的讲述了http module和httpapplication之间的关系,而并没有涉及到http module怎么去实现和注册。http module的意义很大,asp.net mvc框架怎么捕获请求的?或者换一种方式来说asp.net mvc框架的入口点在哪里?
http module注册使用
我们直接进入主题来看一下自定义的实现,首先在module使用之前我们要先定义个module,定义很简单,定义个类型并且实现ihttpmodule接口示例代码1-1
代码1-1
复制代码
1 public class custommodule:ihttpmodule
2 {
3 public void dispose()
4 {
5 throw new notimplementedexception();
6 }
7
8 public void init(httpapplication context)
9 {
10 context.beginrequest += new eventhandler(context_beginrequest);
11 context.endrequest += new eventhandler(context_endrequest);
12 }
13
14 void context_endrequest(object sender, eventargs e)
15 {
16 ((httpapplication)sender).context.response.write("<h1>请求处理结束后进入自定义module</h1>");
17 }
18
19 void context_beginrequest(object sender, eventargs e)
20 {
21 ((httpapplication)sender).context.response.write("<h1>请求处理开始前进入自定义module</h1><hr>");
22 }
23 }
复制代码
这个时候我们自定义的module就已经定义好了,在custommodule类型的 init()方法中是订阅了httpapplication的事件,在请求处理流程文中说过,这里不作讲解了。
这个时候运行程序是不行的,asp.net有天大的本事也不知道你自己自定义了一个module的阿,你得告诉它我这有个自定义的module,运行的时候要执行我的这个module。
现在我们来把module注册到中,打开项目中的web.config配置文件,找到<system.web>节点添加<httpmodules>节点.
代码1-2
<system.web>
<httpmodules>
<add name="mycustommodule" type="mapplication.custommodule,mvcapplication"/>
</httpmodules>
</system.web>
这里要说的是name属性“mycustommodule”值只是module注册到系统的名称,可通过httpapplication实例对象.modules["mycustommodule"]的方式根据name获取到已经注册到系统中的module
type属性值则为自定义的custommodule类型所在的命名空间已经类型名称,逗号后面的值为custommodule类型所在的程序集名称。
这个时候还是不能运行程序的,因为博主的示例程序是使用mvc框架的项目,所以要添加一个空的控制器和一个视图。
右击controllers文件夹添加->控制器,设置名称为homecontroller,设置控制器模板为空控制器,单击确定后,会看到控制器中有个默认的index()方法。
右击index()方法名称,选择添加视图后弹出对话框点击添加即可。
添加 <h2>自定义module演示</h2><hr /> 到视图
这样我们再看一下项目的运行结果:
urlroutingmodule
这里要说的urlroutingmodule类型就是一个系统定义的module,为什么要讲解它呢?因为从它里面可以看到系统的扩展点,也因为它是路由系统和mvc框架的连接点。
根据前面的篇幅对于路由的学习,可以说是对路由有了一个基础的认识,大家都知道请求的url会去匹配系统的定义的路由模式,然后获得一个routedata这么一个对象实例,然后根据它里面的信息来进行对控制器的生成操作等等后续的一些行为。
我们来看图1来理解urlroutingmodule的作用,或许在实际项目开发中不会自己去扩展这部分内容,但是多了解一下也没有坏处。
图2
urlroutingmodule类型的内部大概实现如代码1-3
代码1-3
复制代码
1 void context_postresolverequestcache(object sender, eventargs e)
2 {
3 httpapplication context = sender as httpapplication;
4 httpcontextwrapper contextwrapper = new httpcontextwrapper(context.context);
5
6 routedata routedata = routetable.routes.getroutedata(contextwrapper);
7
8 requestcontext requestcontext = new requestcontext(contextwrapper, routedata);
9 ihttphandler httphandler = routedata.routehandler.gethttphandler(requestcontext);
10 httphandler.processrequest(context.context);
11 }
复制代码
iroutehandler、ihttphandler
在上面的代码1-3中,httphandler变量是通过routedata对象下的routehandler属性里的gethttphandler()方法来根据请求上下文对象requestcontext获取的。
这里捎带一句,关于requestcontext类型(不是对象类型,是参数上下文类型)在mvc后续的学习中会经常见到,这也算是一种开发中的模式吧,requestcontext对象中封装了httpcontextbase对象和routedata对象。
接着刚才的话题,mvcroutehandler类型已经实现了iroutehandler类型,细心的朋友在前面的文章会发现,在mvc中注册路由的时候为每个自定义路由规则(也就是route对象)实例化的时候是用默认的mvcroutehandler类型,从而会转变到routedata的routehandler属性里,在mvcroutehandler类型的默认实现里,gethttphandler()方法返回的是mvchandler,然后就像上面所说的那样。在ihttphandler接口中定义了一个processrequest()方法,这个方法就是mvc框架中请求->路由->控制器的一个过程。这部分内容会在控制器部分说明。