我有一个控件定义如下:
public partial class MyControl: System.Web.UI.UserControl
{
static int ControlID;
static DataTable table;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ControlID = 0;
table= new DataTable();
}
}
public void Save()
{
//ControlID is 0
//table is empty DataTable
}
public void SetControlID(int id)
{
ControlID = id; //This DOES set id correctly
SqlConnection conn = new SqlConnection(ConnectionString);
SqlCommand command = new SqlCommand(SelectCommand, conn);
command.Parameters.AddWithValue("@ControlID ", ControlID);
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(table);
//table is correctly filled with the correct data
}
}
此控件已添加到我的aspx
页面,如:
<uc:MyControl ID="myCont" runat="server" />
Page_Load
是电话:
myCont.SetControlID(1); //This correctly calls the `SetControlID` method and
//seems to fill the `table` and set `ControlID` to 1.
然而,有一个&#34; Save&#34;调用的页面上的按钮:
myCont.Save();
在此方法中,检查ControlID
和table
会将它们分别显示为0和空DataTable
。
为什么ControlID
和table
不会保留SetControlID
方法中设置的值?
编辑:删除2变量的静态属性没有区别。
编辑#2:我只是想指出我在其他许多页面中都使用过此方法,一切正常。这个有什么不同?
答案 0 :(得分:4)
在ASP.NET中,Page类的生命周期是处理请求的持续时间。也就是当请求进入时,页面的类被实例化,viewstate被反序列化以恢复状态(如果它是Postback),运行事件(如按钮点击),生成响应,然后销毁对象。因此,任何未将其状态保存到视图状态(例如int)的成员都不会在激活期间保留。
此外,代码中的嫌疑人是ControlID和tabe都被声明为静态。这意味着这些值将在页面的所有调用者之间共享(并且每次请求新页面时,将覆盖所有用户的表)。这似乎不对。
答案 1 :(得分:2)
static
变量不是页面级别(实例级别)。每次为任何其他用户等加载页面时,您的静态table
将重置为空表。非常坏的坏主意。
答案 2 :(得分:1)
为了保存数据,您必须使用ViewState。
public partial class MyControl: System.Web.UI.UserControl
{
public int ControlID
{
get
{
if(ViewState["ControlID"]==null)
return 0;
return int.Parse(ViewState["ControlID"].ToString());
}
set
{
ViewState["ControlID"] = value;
}
}
....
}
答案 3 :(得分:0)
我应该将此作为对您已接受的答案的评论。但是,我没有足够的声誉点来评论: - )
我接受了这个,因为它是有效的。我不明白其他使用类似逻辑的页面如何在不使用ViewState的情况下工作。 当我说其他页面时,我指的是我建立的众多应用程序 以前,不只是这个应用程序。 -anothershrubery
我还建议在这种情况下使用viewstate,因为静态成员在所有Web请求会话中共享,因此,您可能会看到不需要的行为。
当你想知道为什么你的代码不起作用时,我会试着给你一个推理:
参考ASP.NET页面生命周期here ...从这里你可以看到在Page的加载事件之后处理用户控件的加载事件。所以,程序流程如下:
Page_Load
中,您正在调用myCont.SetControlID(1)
来设置ControlID&amp;表Page_Load
,您正在重置/初始化ControlID&amp;表myCont.Save()
,在其中您会看到ControlID&amp;的重置值。表希望这有帮助!