public class webform : basepage//继承页面基类
{
private void page_load(object sender, system.eventargs e)
{
title = "hello, world!";//指定页面标题
if ( ! ispostback )
{
dropdownlist.datasource = getportaldatasource();//调用基类的方法
dropdownlist.datatextfield = "portalname";
dropdownlist.datavaluefield = "portalid";
dropdownlist.databind();
}
}
private void button_click(object sender, system.eventargs e)
{
datagrid.datasource = getsubjectdatasource( dropdownlist.selectedvalue );
datagrid.databind();
}
}
从上可以看出bagepage controller接管了大部分原来controller的工作,使controller变得更简单,更容易修改(为了便于讲解我没有把控件放在basepage中,但是您完全可以那样做),但是随着应用复杂度的上升,用户需求的变化,我们很容易会将不同的页面类型分组成不同的基类,造成过深的继承树;又例如对于一个购物车程序,需要预定义好页面路径;对于向导程序来说路径是动态的(事先并不知道用户的选择)。
面对以上这些应用来说仅仅使用page controller还是不够的,接下来再看看front controller模式。
front controller模式下的webform
page controller的实现需要在基类中为页面的公共部分创建代码,但是随着时间的推移,需求会发生较大的改变,有时不得不增加非公用的代码,这样基类就会不断增大,您可能会创建更深的继承层次结构以删除条件逻辑,这样一来我们很难对它进行重构,因此需要更进一步对page controller进行研究。
front controller通过对所有请求的控制并传输解决了在page controller中存在的分散化处理的问题,它分为handler和command树两个部分,handler处理所有公共的逻辑,接收http post或get请求以及相关的参数并根据输入的参数选择正确的命令对象,然后将控制权传递到command对象,由其完成后面的操作,在这里我们将使用到command模式。
command模式通过将请求本身变成一个对象可向未指定的应用对象提出请求,这个对象可被存储并像其他的对象一样被传递,此模式的关键是一个抽象的command类,它定义了一个执行操作的接口,最简单的形式是一个抽象的execute操作,具体的command子类将接收者作为其一个实例变量,并实现execute操作,指定接收者采取的动作,而接收者具有执行该请求所需的具体信息。

因为front controller模式要比上面两个模式复杂一些,我们再来看看例子的类图:

关于handler的原理请查阅msdn,在这就不多讲了,我们来看看front controller模式的具体实现:
首先在web.config里定义:
<!-- 指定对dummy开头的aspx文件交由handler处理 -->
<httphandlers>
<add verb="*" path="/webpatterns/frontcontroller/dummy*.aspx" type="webpatterns.frontcontroller.handler,webpatterns"/>
</httphandlers>
<!-- 指定名为frontcontrollermap的页面映射块,交由urlmap类处理,程序将根据key找到对应的url作为最终的执行路径,您在这可以定义多个key与url的键值对 -->
<configsections>
<section name="frontcontrollermap" type="webpatterns.frontcontroller.urlmap, webpatterns"></section>
</configsections>
<frontcontrollermap>
<entries>
<entry key="/webpatterns/frontcontroller/dummywebform.aspx" url="/webpatterns/frontcontroller/actwebform.aspx" />
。。。
</entries>
</frontcontrollermap>
修改webform.aspx.cs:
private void button_click( object sender, system.eventargs e )
{
response.redirect( "dummywebform.aspx?requestparm=" + dropdownlist.selectedvalue );
}
当程序执行到这里时将会根据web.config里的定义触发类handler的processrequest事件:
handler.cs:
public class handler : ihttphandler
{
public void processrequest( httpcontext context )
{
command command = commandfactory.make( context.request.params );
command.execute( context );
}
public bool isreusable
{
get
{
return true;
}
}
}
而它又会调用类commandfactory的make方法来处理接收到的参数并返回一个command对象,紧接着它又会调用该command对象的execute方法把处理后参数提交到具体处理的页面。