1、如何构建积木式Web应用如何构建积木式Web应用上下文基本上我们在儿童时代都玩过积木玩具。通过一块块的积木,再加上我们的想象力,就可以构造出非常多不同的风格的建筑。那么, 我们可不可以把这种搭积木的方式应用到我们的web应用上呢。问题web应用通过提供给用户一整套组件(相当于积木),以及一套已经成型的方案(相当于图纸)。用户可以采用类似搭建积木的方式来根据自己的需要制作界面和应用。环境采用 1.0或 1.1预备知识C#,的服务器控件编程,服务器控件生命周期最好具备以下知识Page Controller,Front Controller解决方案1、建立目录结构为了了解如何采用积木块式应用,我们首
2、先建立如下的主题目录结构:在Sheme目录下保存所有的主题,每个主题都采用相同的目录结构。UserControl目录保存最基本的积木块(UserControl),Page目录是积木块组成的页面所形成的UserControl,Css目录保存与积木块同名的css文件来控制UserControl的界面。PageTeamplate.ascx是页面布局框架,根据所请求的页面不同,在PageTemplate的主体位置载入不同Page目录下的ascx文件。2、划分自己的web积木UserControl将web应用分成一块块的积木,每一块积木形成一个UserControl,并且每一个UserControl有一
3、个同名的css文件用来控制界面。最基本的积木块要放在UserControl目录下,而由最基本积木块组成的页面文件放在Page目录下。提示:在一般的web应用中,都会有Header,Footer,Login等等这样的模块,这些模块就可以形成UserControl组成web应用的积木。具体积木块应该根据你的web应用功能来划分,一般来说我们可以把某个功能就划分成一个积木3、构建载入积木块的容器MyPlaceHolder有了UserControl这些积木块之后,就需要有能够自动在应用中载入这些UserControl积木的容器,这就是PlaceHolder。不过,我们需要扩展PlaceHolder的功
4、能达到自动载入UserControl的目的。public class MyPlaceHolder : PlaceHolderprivate string userControl; / 要载入的UserControl目录下的.ascxprivate string pageControl; / 要载入的Page目录下的.ascxpublic MyPlaceHolder() userControl = ; pageControl = ;public string UserControl get return userControl; set userControl = value; public s
5、tring PageControl get return pageControl; set pageControl = value; / 当需要载入多个UserControl时,可以直接调用LoadUserControl / 当只需要载入一个UserControl时,可以调用Clear清除载入过的内容public void Clear() this.Controls.Clear(); / 载入UserControl目录下的.ascx / 以及导入对应的css文件public void LoadUserControl(string UserControl) this.userControl =
6、UserControl; BasePage page = (BasePage)this.Page; / 请参考后面的BasePage的代码 Control control = this.Page.LoadControl(page.Scheme + usercontrol/ + userControl + .ascx); string css = css/ + userControl + .css; / 对应的css文件 if(File.Exists(this.Page.MapPath(page.Scheme+css) page.AddCss(page.Scheme + css); this.C
7、ontrols.Add(control); / 载入Page目录下的.ascx / LoadPage与LoadUserControl的区别是两者载入的.ascx所在的目录不同 / Page目录下的.ascx可以看成是一些搭建主体结构的.ascx,其使用MyPlaceHolder / 来包含最基础的积木块.ascx(在UserControl目录下)public void LoadPage(string PageControl) this.PageControl = PageControl; BasePage page = (BasePage)this.Page; Control control
8、= this.Page.LoadControl(page.Scheme + page/ + pageControl + .ascx); string css = css/ + pageControl + .css; if(File.Exists(this.Page.MapPath(page.Scheme+css) page.AddCss(page.Scheme + css); this.Controls.Add(control);protected override void OnLoad(EventArgs e) base.OnLoad(e); if(!userControl.Equals(
9、string.Empty) LoadUserControl(userControl); public class MyPlaceHolder : PlaceHolderprivate string userControl; / 要载入的UserControl目录下的.ascxprivate string pageControl; / 要载入的Page目录下的.ascxpublic MyPlaceHolder() userControl = ; pageControl = ;public string UserControl get return userControl; set userCon
10、trol = value; public string PageControl get return pageControl; set pageControl = value; / 当需要载入多个UserControl时,可以直接调用LoadUserControl / 当只需要载入一个UserControl时,可以调用Clear清除载入过的内容public void Clear() this.Controls.Clear(); / 载入UserControl目录下的.ascx / 以及导入对应的css文件public void LoadUserControl(string UserContro
11、l) this.userControl = UserControl; BasePage page = (BasePage)this.Page; / 请参考后面的BasePage的代码 Control control = this.Page.LoadControl(page.Scheme + usercontrol/ + userControl + .ascx); string css = css/ + userControl + .css; / 对应的css文件 if(File.Exists(this.Page.MapPath(page.Scheme+css) page.AddCss(page
12、.Scheme + css); this.Controls.Add(control); / 载入Page目录下的.ascx / LoadPage与LoadUserControl的区别是两者载入的.ascx所在的目录不同 / Page目录下的.ascx可以看成是一些搭建主体结构的.ascx,其使用MyPlaceHolder / 来包含最基础的积木块.ascx(在UserControl目录下)public void LoadPage(string PageControl) this.PageControl = PageControl; BasePage page = (BasePage)this.
13、Page; Control control = this.Page.LoadControl(page.Scheme + page/ + pageControl + .ascx); string css = css/ + pageControl + .css; if(File.Exists(this.Page.MapPath(page.Scheme+css) page.AddCss(page.Scheme + css); this.Controls.Add(control);protected override void OnLoad(EventArgs e) base.OnLoad(e); i
14、f(!userControl.Equals(string.Empty) LoadUserControl(userControl); 使用方法:/ 这里的Header是位于UserControl目录下的Header.ascx4构建主要的建筑结构PageTemplate.ascxPageTemplate其实也是一个UserControl,只不过其功能是用来包含其他的UserControl积木,在PageTemplate里,可以定义页面的整体布局。比如:Header、Footer在整个页面中的位置,页面主体区域的位置等等。更重要的是,PageTemplate中应该包含Form的定义,这是所需要的不可
15、缺少的服务器控件。构建积木式应用程序 BODY margin-left : 0px; margin-right : 0px; 在这个PageTemplate中,我们可以看到使用了4个MyPlaceHolder来载入积木块,除了PageBody这个外,其他的都载入了位于UserControl目录下最基本的积木块。而PageBody的作用则是根据http所请求的页面不同载入Page目录下不同的页面。这些其对应的cs代码在BasePage中处理。public class BasePage : Page public string Scheme =
16、 /Scheme/blue/; / 所采用的主题 public AppSetting Setting; / 环境配置,在Init中分析,其内容包括解析http请求到正确的Page目录下的 / 文件,建立当前登陆用户的信息 public Control focusControl; / 当页面载入后,首先获得焦点的控件 private Literal CssHolder; / 要导入的css private Literal ScriptHolder; / 要导入的script文件 public BasePage() focusControl = null; / 导入css文件引用 public v
17、oid AddScript(string script) / 进行IsPostBack判断的原因是 / 防止重复导入 if(!this.IsPostBack) ScriptHolder.Text += string.Format(n, script); / 导入script文件引用 public void AddCss(string css) if(!this.IsPostBack) CssHolder.Text += n; / 载入http请求分析后的Page目录下的所请求的文件 public void LoadPageTemplate() Control control = (Contro
18、l)this.LoadControl(this.Scheme+PageTemplate.ascx);CssHolder = (Literal)control.FindControl(CssHolder); ScriptHolder = (Literal)control.FindControl(ScriptHolder); this.Controls.Add(control); MyPlaceHolder body = (MyPlaceHolder)control.FindControl(PageBody);body.LoadPage(this.Setting.TargetPage);/ 调用M
19、yPlaceHolder的LoadPage方法/ TargetPage记录了请求的页面 protected override void OnInit(EventArgs e) base.OnInit(e); / 分析http请求 Setting = new AppSetting(this.Request.Path); / 设置用户信息 if(this.Request.IsAuthenticated) Setting.SetUser(User.Identity.Name); protected override void OnLoad(EventArgs e) base.OnLoad(e); t
20、his.LoadPageTemplate(); / 当页面显示后,初始获得焦点的控件 protected void SetFocusControl() if(this.focusControl=null) return; string template = document.all.0.focus(); string script = string.Format(template, this.focusControl.ClientID); this.RegisterStartupScript(FocusControl, script); protected override void OnPr
21、eRender(EventArgs e) base.OnPreRender(e); SetFocusControl(); / 修复了 1.1的一个bug / 没有这段代码,LinkButton等某些服务器将无法使用 protected override void Render(HtmlTextWriter writer) StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); HtmlTextWriter htmlWriter
22、= new HtmlTextWriter(stringWriter); base.Render(htmlWriter); string html = stringBuilder.ToString(); int start = html.IndexOf(form name=) + 12; int end = html.IndexOf(, start); string formID = html.Substring(start, end - start); string replace = formID.Replace(:, _); html = html.Replace(document.+fo
23、rmID,document.+replace);writer.Write(html); BasePage中的一个非常重要的成员变量Setting,其作用是保存分析http请求后的结果。由于采用积木式应用,用户所请求的aspx文件在硬盘上并不存在,需要把用户的这种http请求解析成Page目录下的某个ascx文件,让BasePage载入。5、采用HttpHandler截获http请求有了这些基础性的东西之后,我们就应该使用Front Contrller模式来控制所请求的aspx文件,再把这些请求的文件导向正确的UserControl积木。.NET framework中的Page继承了IhttpHandler,因此我们可以对aspx的解析就让BasePage来处理,这样BasePage在分析了http请求之后,会载入PageTemplate,然后再根据所请求的页面载入不同的UserControl积木。在web.config中进行如下配置,让httphandler生效:我们在这里不是直接使用了HttpHandler,而是采用了HttpHandlerFactory,不过所使用的代码也非常简单
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1