CommunityServer中的代码页面分离
第一步:找一个页面。
首先找到一个页面:CS2008_4.0.30417.1769.sdk\source\Web\Themes\calypso\Common\login.aspx
第二步:找一个处理逻辑的控件
发现该页面中有个控件:CSControl:LoginForm。
代码如下:
其次:如何得到这些控件ID:
再次:
在AttachChildControls方法中通过上下文取得这些控件。
得到控件后,设置提交按钮的事件:
好了,代码与页面分离了。
第五步:看看还有些什么东西:
页面代码中有DisplayConditions, SuccessActions等标签。
我想了解一下DisplayConditions是干什么的?怎么办,查看基类WrappedFormBase。
第六步:查看WrappedFormBase
查看WrappedFormBase发现其中有多个标签,例如DisplayConditions,LeaderTemplate, FormTemplate,TrailerTemplate 。
估计都是页面代码中的标签吧。就像DisplayConditions一样。也是一种控件。
这些控件没有runat=server的属性,所以通过viewstate来取得信息。
基类都对这些标签做了什么呢?
将这些控件添加到Controls集合中。
过程:
这些控件是通过Add方法添加的【也通过页面html】,然后供CreateControlHierarchy方法调用【功能:创建控件体系】,被
第七步:拿DisplayConditions说事:
现在拿DisplayConditions来说吧。
DisplayConditions如何添加到LoginForm中已经知道了,但是这个控件做什么用呢?
DisplayConditions的作用应该是判断当前页面是否满足现实的条件。
代码
CreateChildControls调用【创建子控件到Controls中,CreateChildControls为Control类提供的虚函数】。
<DisplayConditions Operator="Or">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />
<CSControl:Conditions runat="server" Operator="Not">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type" Operator="IsSetOrTrue" runat="server" />
</CSControl:Conditions>
</DisplayConditions>
的作用其实是:
判断当前请求中,参数Type是否等于Password,如果不等于,则判断是否不包含Type参数,如果有一项成立,则可以显示。
这明显是后台逻辑,如何通过页面实现呢?当然是通过上面的html代码。
在WrappedFormBase类中,
方法OnPreRender,在DisplayConditions返回值为false时,不做任何处理,否则调用 base.OnPreRender(e);
OnPreRender: 引发 PreRender 事件。 在加载 Control 对象之后、呈现之前发生。
DisplayConditions为Conditions类型。
查看Conditions代码知道:它的作用是本控件组合其他控件以支持复杂的逻辑.
根据页面代码知道,DisplayConditions的当前逻辑为OR,只要<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />和<CSControl:Conditions runat="server" Operator="Not">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type" Operator="IsSetOrTrue" runat="server" />
</CSControl:Conditions>中有一个为true就可以。
看QueryStringPropertyValueComparison :
作用:验证一个请求中的某个参数是否与某个数值之间存在某种关系。
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />
这样就把逻辑写道页面中了。
总结:
WrappedFormBase类:
功能:
/// 1:定义各种控件。例如Action控件,并把创建的控件添加到Controls集合中,并实现各个控件所含的 逻辑,例如DisplayConditions。
/// 如果不满足DisplayConditions的条件,则不执行PreRender 事件。
/// 2:根据“ControlIdsToHideWhenNotVisible”属性,隐藏需要隐藏的控件。
/// 3:对控件及子控件进行数据绑定.
这其中的应用对HttpContext和CSContext有很大的依赖。
判断请求中是否存在type参数及是否等于Password。
首先找到一个页面:CS2008_4.0.30417.1769.sdk\source\Web\Themes\calypso\Common\login.aspx
第二步:找一个处理逻辑的控件
发现该页面中有个控件:CSControl:LoginForm。
代码如下:
<CSControl:LoginForm runat="server"
AutoLoginCheckBoxId="autoLogin" UserNameTextBoxId="username"
PasswordTextBoxId="password" LoginButtonId="loginButton">
<!--判断参数Type是否等于Password,如果不等于,则判断是否不包含Type参数,如果有一项成立,则可以显示-->
<DisplayConditions Operator="Or">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />
<CSControl:Conditions runat="server" Operator="Not">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type" Operator="IsSetOrTrue" runat="server" />
</CSControl:Conditions>
</DisplayConditions>
<SuccessActions>
<CSControl:GoToReferralUrlAction runat="server" />
<CSControl:GoToSiteUrlAction UrlName="home" runat="server" />
</SuccessActions>
<FormTemplate>
<div class="CommonFormArea">
<asp:Panel runat="server" DefaultButton="loginButton">
<table cellspacing="1" border="0" cellpadding="5">
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="username" runat="server" ResourceName="Login_UserName" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" id="username" runat="server" Columns="30" maxlength="64" />
</td>
</tr>
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="password" runat="server" ResourceName="Login_Password" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" TextMode="Password" id="password" runat="server" Columns="11" maxlength="64" />
<span class="txt4">(<CSControl:SiteUrl UrlName="user_ForgotPassword" ResourceName="Utility_ForumAnchorType_UserForgotPassword" runat="server" />)</span>
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<asp:CheckBox type="checkbox" Checked="true" runat="server" id="autoLogin" /> <CSControl:FormLabel LabelForId="autologin" runat="server" ResourceName="LoginSmall_AutoLogin" />
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<CSControl:ResourceLinkButton id="loginButton" runat="server" CssClass="CommonTextButton Big" ResourceName="LoginSmall_Button" />
</td>
</tr>
</table>
</asp:Panel>
</div>
<CSControl:PlaceHolder runat="server">
<DisplayConditions Operator="not">
<CSControl:SiteSettingsPropertyValueComparison ComparisonProperty="AccountActivation" Operator="equalTo" ComparisonValue="InvitationOnly" runat="server" />
</DisplayConditions>
<ContentTemplate>
</div>
<div>
<CSControl:ResourceControl runat="server" ResourceName="Login_NotMemberYet" />
<CSControl:SiteUrl runat="server" UrlName="user_Register" ResourceName="Login_JoinLink" />
</ContentTemplate>
</CSControl:PlaceHolder>
</FormTemplate>
</CSControl:LoginForm>
第三步:找到该控件的类
找到该控件:CSControl:LoginForm
在CommunityServerControls20的Forms文件夹下。
父类是:WrappedFormBase。
第四步:该类是如何响应事件。
首先,该类定义了四个控件,用户名、密码两个文本框,提交按钮,是否自登录单单选按钮。
在页面中有对应代码:
AutoLoginCheckBoxId="autoLogin" UserNameTextBoxId="username"
PasswordTextBoxId="password" LoginButtonId="loginButton">
<!--判断参数Type是否等于Password,如果不等于,则判断是否不包含Type参数,如果有一项成立,则可以显示-->
<DisplayConditions Operator="Or">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />
<CSControl:Conditions runat="server" Operator="Not">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type" Operator="IsSetOrTrue" runat="server" />
</CSControl:Conditions>
</DisplayConditions>
<SuccessActions>
<CSControl:GoToReferralUrlAction runat="server" />
<CSControl:GoToSiteUrlAction UrlName="home" runat="server" />
</SuccessActions>
<FormTemplate>
<div class="CommonFormArea">
<asp:Panel runat="server" DefaultButton="loginButton">
<table cellspacing="1" border="0" cellpadding="5">
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="username" runat="server" ResourceName="Login_UserName" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" id="username" runat="server" Columns="30" maxlength="64" />
</td>
</tr>
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="password" runat="server" ResourceName="Login_Password" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" TextMode="Password" id="password" runat="server" Columns="11" maxlength="64" />
<span class="txt4">(<CSControl:SiteUrl UrlName="user_ForgotPassword" ResourceName="Utility_ForumAnchorType_UserForgotPassword" runat="server" />)</span>
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<asp:CheckBox type="checkbox" Checked="true" runat="server" id="autoLogin" /> <CSControl:FormLabel LabelForId="autologin" runat="server" ResourceName="LoginSmall_AutoLogin" />
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<CSControl:ResourceLinkButton id="loginButton" runat="server" CssClass="CommonTextButton Big" ResourceName="LoginSmall_Button" />
</td>
</tr>
</table>
</asp:Panel>
</div>
<CSControl:PlaceHolder runat="server">
<DisplayConditions Operator="not">
<CSControl:SiteSettingsPropertyValueComparison ComparisonProperty="AccountActivation" Operator="equalTo" ComparisonValue="InvitationOnly" runat="server" />
</DisplayConditions>
<ContentTemplate>
</div>
<div>
<CSControl:ResourceControl runat="server" ResourceName="Login_NotMemberYet" />
<CSControl:SiteUrl runat="server" UrlName="user_Register" ResourceName="Login_JoinLink" />
</ContentTemplate>
</CSControl:PlaceHolder>
</FormTemplate>
</CSControl:LoginForm>
第三步:找到该控件的类
找到该控件:CSControl:LoginForm
在CommunityServerControls20的Forms文件夹下。
父类是:WrappedFormBase。
第四步:该类是如何响应事件。
首先,该类定义了四个控件,用户名、密码两个文本框,提交按钮,是否自登录单单选按钮。
在页面中有对应代码:
<FormTemplate>
<div class="CommonFormArea">
<asp:Panel runat="server" DefaultButton="loginButton">
<table cellspacing="1" border="0" cellpadding="5">
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="username" runat="server" ResourceName="Login_UserName" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" id="username" runat="server" Columns="30" maxlength="64" />
</td>
</tr>
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="password" runat="server" ResourceName="Login_Password" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" TextMode="Password" id="password" runat="server" Columns="11" maxlength="64" />
<span class="txt4">(<CSControl:SiteUrl UrlName="user_ForgotPassword" ResourceName="Utility_ForumAnchorType_UserForgotPassword" runat="server" />)</span>
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<asp:CheckBox type="checkbox" Checked="true" runat="server" id="autoLogin" /> <CSControl:FormLabel LabelForId="autologin" runat="server" ResourceName="LoginSmall_AutoLogin" />
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<CSControl:ResourceLinkButton id="loginButton" runat="server" CssClass="CommonTextButton Big" ResourceName="LoginSmall_Button" />
</td>
</tr>
</table>
</asp:Panel>
</div>
<CSControl:PlaceHolder runat="server">
<DisplayConditions Operator="not">
<CSControl:SiteSettingsPropertyValueComparison ComparisonProperty="AccountActivation" Operator="equalTo" ComparisonValue="InvitationOnly" runat="server" />
</DisplayConditions>
<ContentTemplate>
</div>
<div>
<CSControl:ResourceControl runat="server" ResourceName="Login_NotMemberYet" />
<CSControl:SiteUrl runat="server" UrlName="user_Register" ResourceName="Login_JoinLink" />
</ContentTemplate>
</CSControl:PlaceHolder>
</FormTemplate>
<div class="CommonFormArea">
<asp:Panel runat="server" DefaultButton="loginButton">
<table cellspacing="1" border="0" cellpadding="5">
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="username" runat="server" ResourceName="Login_UserName" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" id="username" runat="server" Columns="30" maxlength="64" />
</td>
</tr>
<tr>
<td align="right" class="CommonFormFieldName">
<CSControl:FormLabel LabelForId="password" runat="server" ResourceName="Login_Password" />
</td>
<td class="CommonFormField">
<CSControl:DefaultButtonTextBox CssClass="CommonTextBig" ButtonId="loginButton" TextMode="Password" id="password" runat="server" Columns="11" maxlength="64" />
<span class="txt4">(<CSControl:SiteUrl UrlName="user_ForgotPassword" ResourceName="Utility_ForumAnchorType_UserForgotPassword" runat="server" />)</span>
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<asp:CheckBox type="checkbox" Checked="true" runat="server" id="autoLogin" /> <CSControl:FormLabel LabelForId="autologin" runat="server" ResourceName="LoginSmall_AutoLogin" />
</td>
</tr>
<tr>
<td></td>
<td align="left" class="CommonFormField" nowrap="nowrap">
<CSControl:ResourceLinkButton id="loginButton" runat="server" CssClass="CommonTextButton Big" ResourceName="LoginSmall_Button" />
</td>
</tr>
</table>
</asp:Panel>
</div>
<CSControl:PlaceHolder runat="server">
<DisplayConditions Operator="not">
<CSControl:SiteSettingsPropertyValueComparison ComparisonProperty="AccountActivation" Operator="equalTo" ComparisonValue="InvitationOnly" runat="server" />
</DisplayConditions>
<ContentTemplate>
</div>
<div>
<CSControl:ResourceControl runat="server" ResourceName="Login_NotMemberYet" />
<CSControl:SiteUrl runat="server" UrlName="user_Register" ResourceName="Login_JoinLink" />
</ContentTemplate>
</CSControl:PlaceHolder>
</FormTemplate>
其次:如何得到这些控件ID:
<CSControl:LoginForm runat="server"
AutoLoginCheckBoxId="autoLogin" UserNameTextBoxId="username"
PasswordTextBoxId="password" LoginButtonId="loginButton">
AutoLoginCheckBoxId="autoLogin" UserNameTextBoxId="username"
PasswordTextBoxId="password" LoginButtonId="loginButton">
再次:
在AttachChildControls方法中通过上下文取得这些控件。
UserNameTextBox = CSControlUtility.Instance().FindControl(this, UserNameTextBoxId) as TextBox;
得到控件后,设置提交按钮的事件:
LoginButton.Click += new EventHandler(LoginButton_Click);
好了,代码与页面分离了。
第五步:看看还有些什么东西:
页面代码中有DisplayConditions, SuccessActions等标签。
我想了解一下DisplayConditions是干什么的?怎么办,查看基类WrappedFormBase。
第六步:查看WrappedFormBase
查看WrappedFormBase发现其中有多个标签,例如DisplayConditions,LeaderTemplate, FormTemplate,TrailerTemplate 。
估计都是页面代码中的标签吧。就像DisplayConditions一样。也是一种控件。
这些控件没有runat=server的属性,所以通过viewstate来取得信息。
基类都对这些标签做了什么呢?
将这些控件添加到Controls集合中。
过程:
这些控件是通过Add方法添加的【也通过页面html】,然后供CreateControlHierarchy方法调用【功能:创建控件体系】,被
第七步:拿DisplayConditions说事:
现在拿DisplayConditions来说吧。
DisplayConditions如何添加到LoginForm中已经知道了,但是这个控件做什么用呢?
DisplayConditions的作用应该是判断当前页面是否满足现实的条件。
代码







的作用其实是:
判断当前请求中,参数Type是否等于Password,如果不等于,则判断是否不包含Type参数,如果有一项成立,则可以显示。
这明显是后台逻辑,如何通过页面实现呢?当然是通过上面的html代码。
在WrappedFormBase类中,
方法OnPreRender,在DisplayConditions返回值为false时,不做任何处理,否则调用 base.OnPreRender(e);
OnPreRender: 引发 PreRender 事件。 在加载 Control 对象之后、呈现之前发生。
DisplayConditions为Conditions类型。
查看Conditions代码知道:它的作用是本控件组合其他控件以支持复杂的逻辑.
根据页面代码知道,DisplayConditions的当前逻辑为OR,只要<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />和<CSControl:Conditions runat="server" Operator="Not">
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type" Operator="IsSetOrTrue" runat="server" />
</CSControl:Conditions>中有一个为true就可以。
看QueryStringPropertyValueComparison :
作用:验证一个请求中的某个参数是否与某个数值之间存在某种关系。
<CSControl:QueryStringPropertyValueComparison QueryStringProperty="Type"
Operator="EqualTo" ComparisonValue="Password" runat="server" />
这样就把逻辑写道页面中了。
总结:
WrappedFormBase类:
功能:
/// 1:定义各种控件。例如Action控件,并把创建的控件添加到Controls集合中,并实现各个控件所含的 逻辑,例如DisplayConditions。
/// 如果不满足DisplayConditions的条件,则不执行PreRender 事件。
/// 2:根据“ControlIdsToHideWhenNotVisible”属性,隐藏需要隐藏的控件。
/// 3:对控件及子控件进行数据绑定.
这其中的应用对HttpContext和CSContext有很大的依赖。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构