2011-03-29 59 views
1

这是关于ASP.NET,ViewState,UserControls和丢失我的属性的值。我知道,这是一个经典的问题,尽管我已经在这里和谷歌上寻找解决这个问题的办法,但我没有成功。相反,我测试的东西越多,看起来就越少。ASP.NET/UserControl,ViewState和丢失属性值

最重要的是,我使用的是ext.net及其所谓的DirectMethod,但我不认为这与这个问题有很大关系。还有我有很多问题,我希望这个文本将是相当可读性和可理解=)

的用户控件

我有一个用户控件,Customers.ascx,包含一些属性。 “最”重要的是* _CustomerId *。该_CustomerId设置在代码隐藏在ext.net的“DirectMethod”像这样(从页Customers.aspx下面的代码):

[DirectMethod] 
    public void SetCustomer() 
    { 
     RowSelectionModel sm = GridPanel2.SelectionModel.Primary as RowSelectionModel; 

     if (sm.SelectedRow != null) 
     { 
      uint customerId = uint.Parse(sm.SelectedRow.RecordID); 
      customer_modify._CustomerId = customerId; 
     } 
    } 

的“customer_modify”是为客户定义的用户控件实例的.aspx(一个页面,而不是用户控件):

<asp:Content ID="Content2" ContentPlaceHolderID="CPH_center" runat="server"> 
    <CP:Customer ID="customer_modify" runat="server" _IsCreateMode="false" ViewStateMode="Enabled" /> 
</asp:Content> 

在该页面中,Customers.aspx,我有ext.net GridPanel中列出的客户,当我点击的GridPanel行的(直接)方法SetCustomer被执行。

正如你可以在SetCustomer - 方法看,楼市“_CustomerId”与一个UINT更新,所以让我们来看看属性在用户控件:

public uint _CustomerId 
    { 
     get 
     { 
      object o = ViewState["_CustomerId"]; 
      if (o == null) 
       return 0; 
      return (uint)o; 
     } 
     set 
     { 
      object o = ViewState["_CustomerId"]; 
      ViewState["_CustomerId"] = value; 
      SetCustomer(); 
     } 
    } 

正如你所看到的,我正在使用ViewState-thingie,这是我希望的状态,即属性的价值将被记住。他们不是。

当我点击GridPanel中的某一行时第一次我可以看到(通过打破)ViewState [“_ CustomerId”] == null这是否正常。之后我看到_CustomerId的setter被执行并且ViewState [“_ CustomerId”]被分配了RecordID(uint)。

我现在单击GridPanel中的另一行,并再次执行SetCustomer方法。我在_CustomerId的setter中断,并查看ViewState [“_ CustomerId”]在赋值之前是什么。 它是0,但我希望它是上一行单击的值。

为什么是0?我错过了什么?

另外:

我实际上有两个出现在页面上的用户控件的,另一种名为“customer_create”:

<ext:Window 
     ID="Window_CreateNewCustomer" 
     runat="server" 
     Icon="New" 
     Title="Skapa ny kund" 
     Hidden="true" 
     Width="480" 
     Height="370" 
     Modal="true"> 

     <Content> 
      <CP:Customer ID="customer_create" runat="server" Title="Skapa ny kund" _IsCreateMode="true" /> 
     </Content> 
</ext:Window> 

什么扰乱了我很多的是,每​​一次我单击GridPanel中的一行,用户控件中的Page_Load被执行两次,尽管我只是在SetCustomer()方法中更新其中的一个。

这是为什么?

任何提示,想法和帮助将不胜感激。

回答

2

ViewState被序列化,加密并作为隐藏表单字段发送到客户端,以便在某些事件触发表单提交时重新创建。 A [DirectMethod]没有通过表单提交(它是作为AJAX调用处理的),因此它既不能读取也不能写入ViewState数据,除非特别要求以ViewStateMode.Enabled来请求这些数据的往返。

在任何针对表单的请求中,Load事件将从页面中触发,并因此被预订阶段page processing lifecycle中订阅事件的页面上的每个用户控件接收 - 无论是两个一个UserControl或两个不同UserControl的实例,它是两个订户,因此有两个调用(每个实例一个)。

+0

感谢您的回答。这让我以正确的方式。解决方案很简单,只需将“ViewStateMode = Ext.Net.ViewStateMode.Enabled”添加到DirectMethod属性中,如下所示:[DirectMethod(ViewStateMode = Ext.Net.ViewStateMode.Enabled)]。在我刚刚做的一个快速测试中,ViewState按预期保存=) – Ted 2011-03-29 22:00:30

+0

尽管我只是更新一个UserControl,但Page_Load仍然执行了两次,你能说几句话吗? =) – Ted 2011-03-29 22:02:13

+0

我只是添加一个快速评论来确认,但是......默认情况下,ViewState不会在Ext.NET中的DirectMethod或DirectEvent请求中发送。正如您发现的那样,您可以通过设置ViewStateMode = Enabled来覆盖此功能。 – 2011-03-31 20:00:57