Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
425 views
in Technique[技术] by (71.8m points)

c# - ASP.net Null Reference Exception Due to Not Finding Controls

I am having this exception that I can't figure out why it is happening. I searched this site and others trying to find a solution but none have worked so far.

The Problem

I have the following two div in my .aspx page.

<div ID="success" style="visibility:hidden" runat="server">
// buttons and textfields
</div>

<div ID="fail" style="visibility:hidden" runat="server">
// buttons and textfields
</div>

On page load, I want one to become Visible depending on some criterion. But when I try to target them in code behind to change their visibility, it gives me a NullReferenceException pointing to the code trying to change their visibility.

The Code

This is the code I'm using in the code behind.

fail.Style.Add("visibility", "hidden");
success.Style.Add("visibility", "Visible");

I have also tried:

fail.Attributes.Add("style", "visibility:Visible");
success.Attributes.Add("style", "visibility:Visible");

I have done this exact same action on another .aspx page and it didn't give me this NullReferenceException on that page. So I have no idea what's going on. Can someone help please?


The code for newBin.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Data.Common;

namespace SMTInventory
{
    public partial class newBin : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.PreviousPage != null)
            {
                HiddenField pkid_box = (HiddenField)Page.PreviousPage.FindControl("locationID");
                string pkid = pkid_box.Value;
                locationID.Value = pkid;
                success.Style.Add("visibility", "Visible");
            }
            else
            {
                if (Page.FindControl("fail") != null)
                {
                    fail.Style.Add("visibility", "hidden");
                    success.Style.Add("visibility", "Visible");
                }
                else
                {
                    fail.Style.Add("visibility", "hidden");
                    success.Style.Add("visibility", "Visible");
                }

            }
        }

        protected void btnNewLocation_Click(object sender, EventArgs e)
        {
            Server.Transfer("newLocation.aspx", true);
        }

        protected void btnNewBin_Click(object sender, EventArgs e)
        {

        }
    }
}

The code for newBin.aspx

<%@ Page Title="New Bin" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="newBin.aspx.cs" Inherits="SMTInventory.newBin" %>

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <hgroup class="title">
        <h1><%: Title %>.</h1>
        <h2>Add a New Bin</h2>
    </hgroup>

    <article>
        <div ID="success" style="visibility:hidden" runat="server">
            <asp:HiddenField ID="locationID" value="" runat="server" />
            How many racks are in this bin? <asp:TextBox ID="binCount" runat="server" /><br />
            <asp:button id="btnNewBin" onclick="btnNewBin_Click" runat="server" text="Add Bin" />
        </div>

        <div ID="fail" style="visibility:hidden" runat="server">
            <p>This page cannot be used without first creating a new location.<br /></p>
            <asp:Button ID="btnNewLocation" onclick="btnNewLocation_Click" runat="server" Text="Create New Location" />
        </div>
    </article>

    <aside>
        <h3>Aside Title</h3>
        <p>        
            Use this area to provide additional information.
        </p>
        <ul>
            <li><a runat="server" href="~/">Home</a></li>
            <li><a runat="server" href="~/About">About</a></li>
            <li><a runat="server" href="~/Contact">Contact</a></li>
        </ul>
    </aside>
</asp:Content>

Part of Site.Master

<div id="body">
        <asp:LoginView runat="server" ViewStateMode="Disabled">
            <AnonymousTemplate>
                <asp:ContentPlaceHolder runat="server" ID="FeaturedContent" />
                <section class="content-wrapper main-content clear-fix">
                    <asp:ContentPlaceHolder runat="server" ID="MainContent" />
                </section>
                <asp:ContentPlaceHolder runat="server" ID="NewContent" />
            </AnonymousTemplate>
            <LoggedInTemplate>

            </LoggedInTemplate>
        </asp:LoginView>
    </div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In my experience, DIV's are not registered to the server like ASP controls are so calling them directly would produce bad results. When making changes to the controls, i.e. adding styles, make sure you tell ASP what kind of control you have.

For example:

HtmlGenericControl _fail = (HtmlGenericControl)Page.FindControl("fail");

_fail.Style.Item("visibility") = "hidden";

Edit: The problem lies with the ContentPlaceHolder being nested in the LoginView. Drilling down to the controls should expose them.

Example:

LoginView temp = (LoginView)this.Master.FindControl("LoginView1");
ContentPlaceHolder tempp = (ContentPlaceHolder)temp.FindControl("MainContent");
HtmlGenericControl _fail = (HtmlGenericControl)tempp.FindControl("fail");

If you create some class variables to point to these controls and assign them on page load, you can then call them from wherever you want in your code.

To add further confusion to the solution, if you only add:

LoginView temp = (LoginView)this.Master.FindControl("LoginView1");
ContentPlaceHolder tempp = (ContentPlaceHolder)temp.FindControl("MainContent");

to Page_Load and nothing else, it exposes the controls so you can call fail.Style.Add("visibility", "hidden") directly. There seems to be some delay as to when the controls are enumerated by ASP. Calling FindControls() on LoginView, appears to refresh the control "cache" exposing the controls as you would expect them to be.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...