用户控件不保留私有值,返回在Page_Load中设置的值

时间:2014-05-29 13:25:28

标签: c# asp.net user-controls

我有一个控件定义如下:

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();

在此方法中,检查ControlIDtable会将它们分别显示为0和空DataTable

为什么ControlIDtable不会保留SetControlID方法中设置的值?

编辑:删除2变量的静态属性没有区别。

编辑#2:我只是想指出我在其他许多页面中都使用过此方法,一切正常。这个有什么不同?

4 个答案:

答案 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的加载事件之后处理用户控件的加载事件。所以,程序流程如下:

  1. 在Page Page_Load中,您正在调用myCont.SetControlID(1)来设置ControlID&amp;表
  2. 然后发生用户控制Page_Load,您正在重置/初始化ControlID&amp;表
  3. 稍后会调用myCont.Save(),在其中您会看到ControlID&amp;的重置值。表
  4. 希望这有帮助!