第二次页面回发时,ViewState不会在回发时保存

时间:2009-12-17 19:44:14

标签: asp.net asp.net-ajax postback viewstate

我有一个ASP.NET页面,其中包含一个名为ReportCtrl的用户控件(我自己的控件与报表服务等无关)。 ReportCtrl有一个名为TreeViewCtrl的用户控件,它包含一个带有一些时髦的业务逻辑的Telerik TreeView来显示节点。

TreeView放在ASP.NET AJAX面板中。当用户单击可检查节点时,它会回发到服务器并将新的Mapping对象(标记为Serializable)保存到存储在ViewState中的List中。

我遇到的问题是: -

  1. 选中第一个复选框后,该项目将保存到List中,然后将其添加到ViewState。
  2. 选中第二个复选框后,该项目将保存到List中,然后将其添加到ViewState。
  3. 选中第三个复选框后,加载的ViewState中只有1个项目。
  4. 我已经覆盖了检查ViewState中的项目数,我可以看到当选中第二项时,SaveViewState正在保存包含3个项目的ViewState。当在第三个复选框上调用LoadViewState时,我可以看到解码的ViewState中只有1个项目。

    protected override void LoadViewState(object savedState)
    protected override object SaveViewState()
    

    不知何故,Viewstate仅适用于1个项目,仅适用于FIRST项目。

    我们已经确认这与Telerik TreeView无关,只需删除它,只需在按钮点击事件上手动添加项目即可。我们还通过存储字符串列表来消除对象。

    我们对于尝试什么的想法很新鲜。有没有人遇到过这个问题?我们可以尝试任何想法吗?

    感谢。

    CODE

    以下是UpdatePanel的代码:

    <asp:UpdatePanel runat="server" ID="upnlTreeView" ChildrenAsTriggers="true" 
            RenderMode="Inline" UpdateMode="Conditional" EnableViewState="true">
    <ContentTemplate>
        <telerik:RadAjaxManager runat="server" ID="RadAjaxManager1">
            <AjaxSettings>
                <telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="ClickedNodeLabel" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
            </AjaxSettings>
        </telerik:RadAjaxManager>
            <telerik:RadTreeView ID="RadTreeView1" runat="server" Width="100%" Height="420px"
                PersistLoadOnDemandNodes="true" LoadingStatusPosition="BelowNodeText" CausesValidation="false"
                OnClientNodePopulated="nodePopulated" OnClientNodePopulating="nodePopulating" OnClientLoad="onLoad"
                CheckBoxes="true" CheckChildNodes="false" AllowNodeEditing="false" MultipleSelect="false" 
                LoadingMessage="Loading..." AppendDataBoundItems="true" Skin="Vista" EnableViewState="true" 
                onnodecheck="RadTreeView1_NodeCheck"  >
    
                <ExpandAnimation Type="none" />
                <CollapseAnimation Type="none" />
                <WebServiceSettings Path="/ESConsole/ws/PTService.asmx" Method="GetNodes" />
    
            </telerik:RadTreeView>
    
    </ContentTemplate>
    

    以下是代码背后的List定义和其他方法的代码:

        public List<ECodeMapping> ECodeMappings
        {
            get
            {
                return (ViewState["__lstECodeMapping"] == null) ? new List<ECodeMapping>()
                    : ViewState["__lstECodeMapping"] as List<ECodeMapping>;
            }
            set { ViewState["__lstECodeMapping"] = value; }
        }
        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            int count1 = (ViewState["__lstECodeMapping"] as List<ECodeMapping>).Count;
        }
    
        protected override object SaveViewState()
        {
            int count1 = (ViewState["__lstECodeMapping"] as List<ECodeMapping>).Count;
            return base.SaveViewState();
        }
        protected void RadTreeView1_NodeCheck(object sender, RadTreeNodeEventArgs e)
        {
            RadTreeNode node = e.Node;
            int iLevel = node.Attributes["Level"].ToSafeInt();
            if (iLevel == 2)
            {
                var nList = ECodeMappings.FindAll(x => x.DocId == node.Value.ToSafeInt() && x.SecId < 1);
                if (nList.Count() == 0 && node.Checked == true)
                {
                    // Add the node if it doesn't exist
                    ECodeMapping newMapping = new ECodeMapping { ReportId = ReportId, DocId = node.Value.ToSafeInt(), SecId = int.MinValue };
                    ECodeMappings.Insert(0, newMapping);
                    return;
                }
    

2 个答案:

答案 0 :(得分:0)

UpdatePanel实际上是将ViewState发送到服务器并在更新时替换当前的ViewState吗?使用Fiddler或类似工具查看实际的HTTP流量。我猜你没有收到所有更新的ViewState。

答案 1 :(得分:0)

发现问题。

我们在父用户控件中有一个脚本,如下所示: -

BAD CODE

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequest);
var postBackElement;
function EndRequest(sender, args) {
    if (postBackElement.id == '<%= btnUpload.ClientID %>')
        var uprog1 = $get('<%= this.UpdateProgress1.ClientID %>');
        if(uprog1 != null)
        {
         uprog1.style.display = 'none';
        }
        $find('<%= mpeProgress.ClientID %>').hide();
}

此违规脚本必须更改为以下内容: -

好的代码

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequest);
var postBackElement = null;
function EndRequest(sender, args) {
    if (postBackElement != null && postBackElement.id == '<%= btnUpload.ClientID %>')
        var uprog1 = $get('<%= this.UpdateProgress1.ClientID %>');
        if(uprog1 != null)
        {
         uprog1.style.display = 'none';
        }
        $find('<%= mpeProgress.ClientID %>').hide();
}

摘要

需要检查postBackElement是否为空。