ASP.NET / UserControl,ViewState和丢失属性值

时间:2011-03-29 20:54:25

标签: asp.net user-controls properties viewstate ext.net

这是关于ASP.NET,ViewState,UserControls和丢失我的属性的值。我知道这是一个经典的问题,即使我已经在这里和Google上搜索过这个问题的解决方案,但我还没有成功。相反,我测试的东西越多,我理解的就越少。

除此之外,我使用的是ext.net和他们所谓的DirectMethod,但我不认为这与这个问题有很大关系。我有很多问题,我希望这篇文章具有可读性和可理解性=)

UserControl

我有一个UserControl,Customers.ascx,它包含一些属性。 “最重要的”是* _CustomerId *。 _CustomerId在代码隐藏中设置,在ext.net的“DirectMethod”中设置如下(来自Page 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”是Customers.aspx(一个Page,而不是UserControl)中定义的UserControl的实例:

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

在那个页面Customers.aspx中,我有一个列出Customers的ext.net GridPanel,当我点击GridPanel中的行时,执行(直接)方法SetCustomer。

正如您在 SetCustomer -method中所看到的,属性“_CustomerId”使用uint进行更新,所以让我们看一下UserControl中的Property:

    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?我错过了什么?

同时

我实际上在页面上有两个UserControls,另一个名为“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中的一行时,UserControl 中的Page_Load都会被执行两次,即使我只是在SetCustomer中更新其中一个() - 方法

为什么?

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

1 个答案:

答案 0 :(得分:2)

ViewState被序列化,加密并作为隐藏表单字段发送给客户端,以便在某些内容触发表单提交时重构。 [DirectMethod]不会通过表单提交(它作为AJAX调用处理),因此它既不能读取也不能写ViewState数据,除非{{1}特别要求对此数据进行往返}。

在指向表单的任何给定请求中,ViewStateMode.Enabled事件将从页面触发,因此页面上的每个用户控件都会收到{{3的预期阶段的订阅事件 - 无论是一个Load还是两个UserControl的两个实例,它是两个订阅者,因此是两个调用(每个实例一个)。