如何构建积木式Web应用

上下文
问题
环境
预备知识
最好具备以下知识
解决方案
public class MyPlaceHolder : PlaceHolder

{

private string userControl;  // 要载入的UserControl目录下的.ascx

private string pageControl;  // 要载入的Page目录下的.ascx

public MyPlaceHolder()

{

userControl = "";

pageControl = "";

}

public string UserControl

{

get

{

return userControl;

}

set

{

userControl = 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 UserControl)

{

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.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.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);

if(!userControl.Equals(string.Empty))

{

LoadUserControl(userControl);

}

}

}

public class MyPlaceHolder : PlaceHolder

{

private string userControl;  // 要载入的UserControl目录下的.ascx

private string pageControl;  // 要载入的Page目录下的.ascx

public MyPlaceHolder()

{

userControl = "";

pageControl = "";

}

public string UserControl

{

get

{

return userControl;

}

set

{

userControl = 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 UserControl)

{

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.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.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);

if(!userControl.Equals(string.Empty))

{

LoadUserControl(userControl);

}

}

}

使用方法:

<HomeOffice:MyPlaceHolder

id="Myplaceholder1"

runat="server"

UserControl="Header">

</HomeOffice:MyPlaceHolder>

// 这里的Header是位于UserControl目录下的Header.ascx
<%@ Register TagPrefix="HomeOffice"

Namespace="HomeOffice.Web.UI.WebControl"

Assembly = "HomeOffice.Web.UI" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<title>构建积木式应用程序</title>

<asp:Literal ID="CssHolder" runat="server"></asp:Literal>

<asp:Literal ID="ScriptHolder" Runat="server"></asp:Literal>

<style>

BODY { margin-left : 0px; margin-right : 0px; }

</style>

</HEAD>

<body bgcolor="#e6e6e6">

<form id="Form1" method="post" runat="server"

enctype="multipart/form-data">

<table width="100%" cellpadding="0" cellspacing="0">

<tr>

<td>&nbsp;</td>

<td width="800">

<table width="100%" cellpadding="0" cellspacing="0">

<tr>

<td>

<HomeOffice:MyPlaceHolder id="PlaceHolder1"

runat="server" UserControl="Header">

</HomeOffice:MyPlaceHolder>

</td>

</tr>

<tr>

<td>

<HomeOffice:MyPlaceHolder id="Myplaceholder1"

runat="server" UserControl="MainMenu">

</HomeOffice:MyPlaceHolder>

</td>

</tr>

<tr>

<td style="height:6px;background:#f6f6f6;font-size:1px;

border-top:1px solid white;">&nbsp;

</td>

</tr>

<tr>

<td style="height:4px;background:#e1e1e1;font-size:1px;

border-top:1px solid #e6e6e6; ">&nbsp;

</td>

</tr>

<tr>

<td style="background:white;border-bottom:1px solid #bbbbbb">

<HomeOffice:MyPlaceHolder id="PageBody" runat="server">

</HomeOffice:MyPlaceHolder>

</td>

</tr>

<tr>

<td style="padding-top:20px">

<HomeOffice:MyPlaceHolder id="Myplaceholder2"

runat="server" UserControl="Footer">

</HomeOffice:MyPlaceHolder>

</td>

</tr>

</table>

</td>

<td>&nbsp;</td>

</tr>

</table>

</form>

</body>

</HTML>

public class BasePage : Page

{

public string Scheme = "/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 void AddScript(string script)

{

// 进行IsPostBack判断的原因是

// 防止重复导入

if(!this.IsPostBack)

{

ScriptHolder.Text += string.Format("<script src=\"{0}\"

type=\"text/javascript\"></script>\n", script);

}

}

// 导入script文件引用

public void AddCss(string css)

{

if(!this.IsPostBack)

{

CssHolder.Text += "<link rel=\"stylesheet\"

type=\"text/css\" href=\"" + css + "\">\n";

}

}

// 载入http请求分析后的Page目录下的所请求的文件

public void LoadPageTemplate()

{

Control control = (Control)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);

// 调用MyPlaceHolder的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);

this.LoadPageTemplate();

}

// 当页面显示后,初始获得焦点的控件

protected void SetFocusControl()

{

if(this.focusControl==null) return;

string template = @"<script language='jscript'>

document.all.{0}.focus();</script>";

string script = string.Format(template,

this.focusControl.ClientID);

this.RegisterStartupScript("FocusControl", script);

}

protected override void OnPreRender(EventArgs e)

{

base.OnPreRender(e);

SetFocusControl();

}

// 修复了asp.net 1.1的一个bug

// 没有这段代码,LinkButton等某些服务器将无法使用

protected override void Render(HtmlTextWriter writer)

{

StringBuilder stringBuilder = new StringBuilder();

StringWriter stringWriter = new StringWriter(stringBuilder);

HtmlTextWriter htmlWriter = 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."+formID,"document."+replace);

writer.Write(html);

}

}

在web.config中进行如下配置,让httphandler生效:

<httpHandlers>

<add verb="*" path="*.aspx" type="HomeOffice.Web.UI.HttpHandler.MyPageHandlerFactory, HomeOffice.Web.UI"/>

</httpHandlers>

public class MyPageHandlerFactory : IHttpHandlerFactory

{

public virtual IHttpHandler GetHandler(HttpContext context,

String requestType,

String url,

String pathTranslated)

{

return new BasePage();

}

public virtual void ReleaseHandler(IHttpHandler handler)

{

}

}
public class AppSetting

{

public string Url;			// request url

public string Site;			// request site

public string User;			// login name

public string UserName;		// display name

public string TargetPage;		// target page

public string[] Roles;		// user roles in the site

private Hashtable parameter = new Hashtable();

public AppSetting()

{

Site = "default";

User = "*";

UserName = "";

Roles = null;

}

public AppSetting(string url) : this()

{

this.Url = url.ToLower();

AnalysisUrl(this.Url);

}

public object this[string key]

{

get { return parameter[key]; }

set { parameter.Add(key, value); }

}

// 分析用户所请求的页面和参数

protected void AnalysisPage(string url)

{

PageInfo[] pages = XmlHomeOffice.Pages();

foreach(PageInfo page in pages)

{

if(Regex.IsMatch(url,page.pattern,RegexOptions.IgnoreCase))

{

this.TargetPage = string.Format(page.target_page,

url.Replace(".aspx","").Split('/'));

if(!page.parameter.Equals(string.Empty))

{

string p = string.Format(page.parameter,

url.Replace(".aspx", "").Split('/'));

string[] ps = p.Split(',');

foreach(string str in ps)

{

string[] item = str.Split('=');

this[item[0]] = item[1];

}

}

return;

}

}

// No one matched, a Exception occur

this.TargetPage = "error";

}

// 分析出站点,类似于blog中的每个站点

protected string AnalysisSite(string url)

{

if(url[0]=='/')

{

url = url.Remove(0, 1);

}

string[] items = url.Split('/');

if(items.Length<1)

{

return Site + "/default.aspx";

}

if(items[0].EndsWith(".aspx"))

{

return Site + "/" + url;

}

string[] reserved_words = XmlHomeOffice.ReservedWords();

foreach(string str in reserved_words)

{

if(items[0].Equals(str.ToLower()))

{

return Site + "/" + url;

}

}

Site = items[0];

return url;

}

public void AnalysisUrl(string url)

{

Url = AnalysisSite(url);

AnalysisPage(Url);

}

public void SetUser(string user)

{

User = user;

UserName = XmlUsers.GetDisplayName(user);

XmlSiteProfile profile = new XmlSiteProfile(Site);

Roles = profile.SiteUserRole(user);

}

public bool HasRole(string role)

{

if(Roles==null) return false;

foreach(string str in Roles)

{

if(str.Equals(role)) return true;

}

return false;

}

}

  <pages>

<page pattern="^(\/testboth.aspx)$"

parameter="" target-page="testboth" />

<page pattern="^(\/\w+.aspx)$"

parameter="" target-page="{1}" />

</pages>

<%@ Control Language="c#" AutoEventWireup="false"

Inherits="HomeOffice.UserControl.PageTemplate" %>
流程说明
具体应用
优点讨论
下载
建立如下的数据库,表,存储过程:

数据库:test

访问账号:sa,sa(可以在web.config中修改)

表:test

字段 test_id(自增),string(nvarchar(50)),number(int)

存储过程:

testaddnew:(没有参数)

insert into test(string, number) values(‘’, 0);

testget: (没有参数)

select * from test

testdelete:(输入参数:@test_id int)

delete from test where test_id = @teat_id

testupate:(参数:@test_id, @string, @number)

update test set string=@string, number=@number

where test_id=@test_id
http://localhost/testboth.aspx
http://localhost/testtextbox.aspx
http://localhost/testdatagrid.aspx
http://www.smartyouth.net/scheme.rar
相关知识
http://www.microsoft.com/china/msdn/architecture/patterns/Esp/
http://scottwater.com/DotText/default.aspx

你可能感兴趣的:(Web应用)