Сервер контролирует значение null в Page_Load

#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.