ArgumentNullException 的问题
Problems with ArgumentNullException
我在 ASP.NET 项目的 C# class 顶部声明了一个 List<Foo>
类型的变量。在加载方法中,我实例化了这个 class,但是当我尝试在另一个方法中使用这个对象(已经在加载方法中实例化)时,它是空的,给我错误 ArgumentNullException。
我是这样做的:
public partial class Teste : System.Web.UI.Page
{
List<Foo> myList;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
myList = new List<Foo>();
}
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" }); //NullReferenceException - myList is null here!
}
}
这可能很简单,但我是网络表单的新手,所以我不知道这里发生了什么。我知道在 windows 形式中它工作得很好。
我让它工作的唯一方法是声明为静态:
static List<Foo> myList;
但我认为这不是正确的做法。
如有任何帮助,我们将不胜感激。
您必须在每次回发时初始化所有变量,因为所有变量(和控件)都在页面生命周期结束时处理,因此在呈现并发送到客户端之后。
所以替换
if (!IsPostBack)
myList = new List<Foo>();
和
myList = new List<Foo>();
您也不应该在 ASP.NET 中使用 static
字段,因为它们在所有请求中共享。这意味着每个用户都有相同的列表。
如果你想在回发中保留列表,你可以使用 Session
。但我反对这样做。为什么你需要将它存储在服务器内存中?如果您需要将它用作 DataSource
用于 Web 数据绑定控件,例如 Repeater
或 GridView
,则不需要存储它。只需让 ViewState
恢复控件的状态即可。这是默认自动完成的。
在每个 PostbBack
上,您的变量都将为空。您必须提供一种重新生成它的方法。如果您想以简单的方式进行操作,请使用 ViewState
.
if (!IsPostBack)
{
myList = new List<Foo>();
ViewState["myList"] = myList;
}
else
{
myList = (List<Foo>)ViewState["myList"];
}
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" }); //NullReferenceException - myList is null here!
ViewState["myList"] = myList;
}
您仅在 !IsPostBack
时实例化。按钮单击事件是回传。您需要根据您要完成的工作重新设计您的逻辑。 List<Foo>
中存储了什么?如果您打算重复使用或在多个页面上使用,请考虑将对象放入会话缓存中。
将其设置为 static
对 Null Reference Exception 没有帮助。
您需要了解 Page_Load
活动中的检查 if (!IsPostBack)
并记住 Web 是无状态的 。
所以在您的第一个页面加载时,您的列表是实例化的。接下来会发生什么是当你点击你的按钮。现在它是 Post 返回,这将导致 !IsPostBack
检查 return false
。在这里,人们会认为 List
之前已经实例化过,不需要再次实例化。 但是网络是无状态的,所以在 Page_Load
上 List
已经丢失了内容,它又被设置为 null
。
你需要保持你的状态。有多种方法可以做到这一点,我想到了 ViewState
、Session
和 cookie。阅读它们并相应地使用它们。
在你的情况下你可以这样做:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myList = new List<Foo>();
Session["myList"] = myList;
}
else
{
myList = Session["myList"] as List<Foo>;
}
}
并在按钮点击中
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" });
Session["myList"] = myList; //save it back in session
}
这将恢复 post 上的原始列表。但请记住,会话很昂贵,因为它们是在服务器上按用户维护的。
您也可以使用 ViewState
,但这需要一个可序列化的对象。
要制作 class Serializable
请参阅:Basic Serialization - MSDN
[Serializable]
class Foo
{
public int ID { get; set;}
public string Name {get; set;}
}
然后你可以在上面的代码中使用ViewState
代替Session
。 ViewState
的优点是它将在客户端以页面方式进行维护,并且不会像 Session
那样对服务器造成负担。所以你的 ViewState
代码会是这样的:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myList = new List<Foo>();
ViewState["myList"] = myList;
}
else
{
myList = ViewState["myList"] as List<Foo>;
}
}
对于按钮点击:
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" });
ViewState["myList"] = myList; //save it back in session
}
我在 ASP.NET 项目的 C# class 顶部声明了一个 List<Foo>
类型的变量。在加载方法中,我实例化了这个 class,但是当我尝试在另一个方法中使用这个对象(已经在加载方法中实例化)时,它是空的,给我错误 ArgumentNullException。
我是这样做的:
public partial class Teste : System.Web.UI.Page
{
List<Foo> myList;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
myList = new List<Foo>();
}
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" }); //NullReferenceException - myList is null here!
}
}
这可能很简单,但我是网络表单的新手,所以我不知道这里发生了什么。我知道在 windows 形式中它工作得很好。 我让它工作的唯一方法是声明为静态:
static List<Foo> myList;
但我认为这不是正确的做法。
如有任何帮助,我们将不胜感激。
您必须在每次回发时初始化所有变量,因为所有变量(和控件)都在页面生命周期结束时处理,因此在呈现并发送到客户端之后。
所以替换
if (!IsPostBack)
myList = new List<Foo>();
和
myList = new List<Foo>();
您也不应该在 ASP.NET 中使用 static
字段,因为它们在所有请求中共享。这意味着每个用户都有相同的列表。
如果你想在回发中保留列表,你可以使用 Session
。但我反对这样做。为什么你需要将它存储在服务器内存中?如果您需要将它用作 DataSource
用于 Web 数据绑定控件,例如 Repeater
或 GridView
,则不需要存储它。只需让 ViewState
恢复控件的状态即可。这是默认自动完成的。
在每个 PostbBack
上,您的变量都将为空。您必须提供一种重新生成它的方法。如果您想以简单的方式进行操作,请使用 ViewState
.
if (!IsPostBack)
{
myList = new List<Foo>();
ViewState["myList"] = myList;
}
else
{
myList = (List<Foo>)ViewState["myList"];
}
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" }); //NullReferenceException - myList is null here!
ViewState["myList"] = myList;
}
您仅在 !IsPostBack
时实例化。按钮单击事件是回传。您需要根据您要完成的工作重新设计您的逻辑。 List<Foo>
中存储了什么?如果您打算重复使用或在多个页面上使用,请考虑将对象放入会话缓存中。
将其设置为 static
对 Null Reference Exception 没有帮助。
您需要了解 Page_Load
活动中的检查 if (!IsPostBack)
并记住 Web 是无状态的 。
所以在您的第一个页面加载时,您的列表是实例化的。接下来会发生什么是当你点击你的按钮。现在它是 Post 返回,这将导致 !IsPostBack
检查 return false
。在这里,人们会认为 List
之前已经实例化过,不需要再次实例化。 但是网络是无状态的,所以在 Page_Load
上 List
已经丢失了内容,它又被设置为 null
。
你需要保持你的状态。有多种方法可以做到这一点,我想到了 ViewState
、Session
和 cookie。阅读它们并相应地使用它们。
在你的情况下你可以这样做:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myList = new List<Foo>();
Session["myList"] = myList;
}
else
{
myList = Session["myList"] as List<Foo>;
}
}
并在按钮点击中
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" });
Session["myList"] = myList; //save it back in session
}
这将恢复 post 上的原始列表。但请记住,会话很昂贵,因为它们是在服务器上按用户维护的。
您也可以使用 ViewState
,但这需要一个可序列化的对象。
要制作 class Serializable
请参阅:Basic Serialization - MSDN
[Serializable]
class Foo
{
public int ID { get; set;}
public string Name {get; set;}
}
然后你可以在上面的代码中使用ViewState
代替Session
。 ViewState
的优点是它将在客户端以页面方式进行维护,并且不会像 Session
那样对服务器造成负担。所以你的 ViewState
代码会是这样的:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myList = new List<Foo>();
ViewState["myList"] = myList;
}
else
{
myList = ViewState["myList"] as List<Foo>;
}
}
对于按钮点击:
protected void btnTeste_Click(object sender, EventArgs e)
{
myList.Add(new Foo { Id = 0, Name = "Nobody" });
ViewState["myList"] = myList; //save it back in session
}