#asp.net #controls #pageload
#asp.net #элементы управления #загрузка страницы
Вопрос:
У меня есть страница, на которой есть некоторые серверные элементы управления. По какой-то причине эти элементы управления имеют значение null в обработчике события Page_Load страницы.
<asp:Content ID="mainContent" runat="server" ContentPlaceHolderID="mainPlaceholder">
<asp:Label ID="userIdLockedLabel" runat="server" EnableViewState="False" ForeColor="Red"
Visible="False">
</asp:Label>
<asp:Panel ID="standardLoginPanel" runat="server">
<asp:Login ID="loginControl" runat="server"
DisplayRememberMe="false"
PasswordRecoveryUrl="?action=lostpass"
TextBoxStyle-Font-Names="verdana"
TextBoxStyle-Font-Size="Small"
DestinationPageUrl="Home.aspx"
OnLoggingIn="OnLoggingIn"
OnLoginError="OnError"
TitleText="" >
<TextBoxStyle Font-Names="verdana" Font-Size="Small"></TextBoxStyle>
<LoginButtonStyle CssClass="btn" />
</asp:Login>
</asp:Panel>
<asp:Panel ID="canadaLoginPanel" runat="server" Visible="false">
<asp:Label ID="userFailureLabel" runat="server"></asp:Label>
<table>
<tr>
<td><%= Utility.RetrieveResource("CompanyNumberLabel") %></td>
<td><asp:TextBox ID="companyNumberTextbox" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><%= Utility.RetrieveResource("UserIdLabel")%></td>
<td><asp:TextBox ID="userIdTextbox" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><%= Utility.RetrieveResource("PasswordLabel")%></td>
<td><asp:TextBox ID="userPasswordTextbox" runat="server" TextMode="Password"></asp:TextBox></td>
</tr>
<tr>
<td colspan="2">
<asp:CheckBox ID="rememberMeCheckBox" runat="server" />
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><asp:Button ID="userSubmit" runat="server" CssClass="btn" /></td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><a href="ForgotPassword.aspx"><%= Utility.RetrieveResource("ForgotPasswordLinkText") %></a></td>
</tr>
</table>
</asp:Panel>
<br />
<div style="font-family: Verdana; font-size: small">
<span class="bold">
<%= Utility.RetrieveResource("TroubleLogginIn") %>
</span><br />
<%= Utility.RetrieveResource("ForgotPasswordText") %>
</div>
Страница login.aspx наследуется от LogOnBasePage, и именно там находится код Page_Load. Там я использую следующий код:
if (this.Company.SiteType == Ceridian.KB.Entities.SiteType.CAN)
{
this.FindControlRecursive("standardLoginPanel").Visible = false;
this.FindControlRecursive("canadaLoginPanel").Visible = true;
((Button)this.FindControlRecursive("userSubmit")).Text = Utility.RetrieveResource("LoginButtonText");
this.Login = null;
CheckBox rememberMe = (CheckBox)this.FindControlRecursive("rememberMeCheckBox");
rememberMe.Text = Utility.RetrieveResource("RememberMeText");
}
Вот содержимое рекурсивного метода FindControl.
public static Control FindControlRecursive(this Control control, string controlId)
{
if (string.Compare(control.ID, controlId, StringComparison.OrdinalIgnoreCase) == 0)
{
// We found the control!
return control;
}
else
{
// Recurse through ctrl's Controls collections
foreach (Control child in control.Controls)
{
Control lookFor = FindControlRecursive(child, controlId);
if (lookFor != null)
{
// We found the control
return lookFor;
}
}
// If we reach here, control was not found
return null;
}
}
Я всегда получаю нулевую ссылку в первой строке внутри проверки if. Я не понимаю, как это возможно.
Ответ №1:
Возможно, вам нужно подождать позже в жизненном цикле страницы. попробуйте поместить это в событие page_prerendercomplete следующим образом
Page_PreRenderComplete(Object sender, EventArgs e)
{
if (this.Company.SiteType == Ceridian.KB.Entities.SiteType.CAN)
{
this.FindControlRecursive("standardLoginPanel").Visible = false;
this.FindControlRecursive("canadaLoginPanel").Visible = true;
((Button)this.FindControlRecursive("userSubmit")).Text = Utility.RetrieveResource("LoginButtonText");
this.Login = null;
CheckBox rememberMe = (CheckBox)this.FindControlRecursive("rememberMeCheckBox");
rememberMe.Text = Utility.RetrieveResource("RememberMeText");
}
Ответ №2:
Использует ли страница, от которой вы наследуете, файл разметки (например, LogOnBasePage.aspx)?
Если это так, то я думаю, что вам не повезло с наследованием от него. Страница разметки генерирует класс, который наследуется от класса, определенного в коде за страницей. Одной из обязанностей этого сгенерированного класса является создание экземпляров элементов управления, определенных в разметке. Если вы наследуете от LogOnBasePage, на вашей новой странице не будет кода, необходимого для создания элементов управления из разметки LogOnBasePage, и, следовательно, вы получите нулевые ссылки.
Комментарии:
1. Это не так. LogOnBasePage — это класс, определенный в папке AppCode. Он наследуется от другого класса, BasePage, который в конечном итоге наследуется от Page.