ASP.net 由于找不到控件导致空引用异常
ASP.net Null Reference Exception Due to Not Finding Controls
我有这个异常,我不知道为什么会这样。我搜索了这个网站和其他人试图找到解决方案,但 none 到目前为止已经奏效了。
问题
我的 .aspx 页面中有以下两个 div。
<div ID="success" style="visibility:hidden" runat="server">
// buttons and textfields
</div>
<div ID="fail" style="visibility:hidden" runat="server">
// buttons and textfields
</div>
在页面加载时,我希望其中一个根据某些标准变为可见。但是当我尝试在代码隐藏中将它们作为目标以更改它们的可见性时,它会给我一个 NullReferenceException 指向试图改变它们可见性的代码。
代码
这是我在后面的代码中使用的代码。
fail.Style.Add("visibility", "hidden");
success.Style.Add("visibility", "Visible");
我也试过:
fail.Attributes.Add("style", "visibility:Visible");
success.Attributes.Add("style", "visibility:Visible");
我在另一个 .aspx 页面上执行了完全相同的操作,但在该页面上没有给我这个 NullReferenceException。所以我不知道发生了什么。有人可以帮忙吗?
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)
{
}
}
}
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>
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>
根据我的经验,DIV 没有像 ASP 控件那样注册到服务器,因此直接调用它们会产生不好的结果。对控件进行更改时,即添加样式,请确保告知 ASP 您拥有哪种控件。
例如:
HtmlGenericControl _fail = (HtmlGenericControl)Page.FindControl("fail");
_fail.Style.Item("visibility") = "hidden";
编辑:问题在于 ContentPlaceHolder 嵌套在 LoginView 中。向下钻取控件应该会显示它们。
示例:
LoginView temp = (LoginView)this.Master.FindControl("LoginView1");
ContentPlaceHolder tempp = (ContentPlaceHolder)temp.FindControl("MainContent");
HtmlGenericControl _fail = (HtmlGenericControl)tempp.FindControl("fail");
如果您创建一些 class 变量来指向这些控件并在页面加载时分配它们,您就可以在代码中的任意位置调用它们。
如果您只添加:
,则会使解决方案更加混乱
LoginView temp = (LoginView)this.Master.FindControl("LoginView1");
ContentPlaceHolder tempp = (ContentPlaceHolder)temp.FindControl("MainContent");
到 Page_Load 仅此而已,它公开了控件,因此您可以直接调用 fail.Style.Add("visibility", "hidden")。 ASP 枚举控件的时间似乎有些延迟。在 LoginView 上调用 FindControls() 似乎刷新了控件 "cache" 并按照您的预期公开了控件。
我有这个异常,我不知道为什么会这样。我搜索了这个网站和其他人试图找到解决方案,但 none 到目前为止已经奏效了。
问题
我的 .aspx 页面中有以下两个 div。
<div ID="success" style="visibility:hidden" runat="server">
// buttons and textfields
</div>
<div ID="fail" style="visibility:hidden" runat="server">
// buttons and textfields
</div>
在页面加载时,我希望其中一个根据某些标准变为可见。但是当我尝试在代码隐藏中将它们作为目标以更改它们的可见性时,它会给我一个 NullReferenceException 指向试图改变它们可见性的代码。
代码
这是我在后面的代码中使用的代码。
fail.Style.Add("visibility", "hidden");
success.Style.Add("visibility", "Visible");
我也试过:
fail.Attributes.Add("style", "visibility:Visible");
success.Attributes.Add("style", "visibility:Visible");
我在另一个 .aspx 页面上执行了完全相同的操作,但在该页面上没有给我这个 NullReferenceException。所以我不知道发生了什么。有人可以帮忙吗?
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)
{
}
}
}
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>
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>
根据我的经验,DIV 没有像 ASP 控件那样注册到服务器,因此直接调用它们会产生不好的结果。对控件进行更改时,即添加样式,请确保告知 ASP 您拥有哪种控件。
例如:
HtmlGenericControl _fail = (HtmlGenericControl)Page.FindControl("fail");
_fail.Style.Item("visibility") = "hidden";
编辑:问题在于 ContentPlaceHolder 嵌套在 LoginView 中。向下钻取控件应该会显示它们。
示例:
LoginView temp = (LoginView)this.Master.FindControl("LoginView1");
ContentPlaceHolder tempp = (ContentPlaceHolder)temp.FindControl("MainContent");
HtmlGenericControl _fail = (HtmlGenericControl)tempp.FindControl("fail");
如果您创建一些 class 变量来指向这些控件并在页面加载时分配它们,您就可以在代码中的任意位置调用它们。
如果您只添加:
,则会使解决方案更加混乱LoginView temp = (LoginView)this.Master.FindControl("LoginView1");
ContentPlaceHolder tempp = (ContentPlaceHolder)temp.FindControl("MainContent");
到 Page_Load 仅此而已,它公开了控件,因此您可以直接调用 fail.Style.Add("visibility", "hidden")。 ASP 枚举控件的时间似乎有些延迟。在 LoginView 上调用 FindControls() 似乎刷新了控件 "cache" 并按照您的预期公开了控件。