【问题标题】:ASP.NET Session State & Postback problemsASP.NET 会话状态和回发问题
【发布时间】:2014-08-06 15:11:27
【问题描述】:

我有一个问题,我认为是会话状态问题,但我不知道出了什么问题。我有一个示例项目来说明问题。 (下面的代码)我有 2 个按钮。每个都用一些独特的数据填充一个列表,然后使用该数据向表中添加一行。该行包含文本框,以便用户可以编辑数据。 (对于我的示例,没有更新按钮来保存数据。)要在 VS2010 中重现该问题,请创建一个新的“ASP.NET Web 应用程序”项目并将 aspx 代码和 c# 代码隐藏复制/粘贴到 Default.aspx ,然后运行应用程序。

  • 按下 DataSet 1 按钮,网格应填充 1 行。
  • 在其中一个文本框中编辑数据,并在文本框中使用制表符。 (新输入的文本应该是remian,字体应该是蓝色的。这就是我想要的。)
  • 现在单击任一 DataSet 按钮以重置列表并刷新表。 编辑其中一个文本框中的数据,然后在文本框中使用制表符。 (立即,框中的文本刷新回其原始值。不过,这种情况只会发生一次。如果您现在编辑任一文本框,它将正常工作。)
  • 这是可重复的...在按 DataSet 按钮第二次、第三次等后的第一次编辑将重置回原始值。我不知道为什么。

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="DebugPostbackIssue._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Welcome to ASP.NET!
    </h2>
    <p>
        Populate the table with DataSet #1:<asp:Button runat="server" ID="btnDS1" Text="Dataset 1" OnClick="btnDS1_Click" />
    </p>
    <p>
        Populate the table with DataSet #2:<asp:Button runat="server" ID="btnDS2" Text="Dataset 2" OnClick="btnDS2_Click" />
    </p>
    <p>
        <asp:Table runat="server" ID="tblData">
            <asp:TableHeaderRow runat="server" ID="thrData">
                <asp:TableHeaderCell Scope="Column" Text="Column 1"></asp:TableHeaderCell>
                <asp:TableHeaderCell Scope="Column" Text="Column 2"></asp:TableHeaderCell>
            </asp:TableHeaderRow>
        </asp:Table>
    </p>
</asp:Content>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace DebugPostbackIssue
{
    public partial class _Default : System.Web.UI.Page
    {
        private List<string> _MyData = new List<string>();

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Page_Init(object sender, EventArgs e)
        {
            LoadSessionData();
            GenerateGrid(false);
        }

        protected void btnDS1_Click(object sender, EventArgs e)
        {
            _MyData = new List<string>();
            _MyData.Add("111");
            _MyData.Add("aaa");

            SaveSessionData();
            GenerateGrid(true);
        }

        protected void btnDS2_Click(object sender, EventArgs e)
        {
            _MyData = new List<string>();
            _MyData.Add("222");
            _MyData.Add("bbb");

            SaveSessionData();
            GenerateGrid(true);
        }

        private void SaveSessionData()
        {
            Session["MyData"] = _MyData;
        }

        private void LoadSessionData()
        {
            if (Session["MyData"] != null)
                _MyData = (List<string>)Session["MyData"];
            else
                _MyData = new List<string>();
        }

        private void GenerateGrid(bool ClearData)
        {
            if (ClearData)
                while (tblData.Rows.Count > 1)
                    tblData.Rows.Remove(tblData.Rows[tblData.Rows.Count - 1]);

            TableRow tr = new TableRow();

            foreach (string s in _MyData)
            {
                TableCell tc = new TableCell();

                TextBox txtBox = new TextBox();
                txtBox.Text = s;
                txtBox.Attributes.Add("OriginalValue", s);
                txtBox.TextChanged += new EventHandler(txtBox_TextChanged);
                txtBox.AutoPostBack = true;
                tc.Controls.Add(txtBox);

                tr.Cells.Add(tc);
            }

            if (tr.Cells.Count > 0)
                tblData.Rows.Add(tr);
        }

        void txtBox_TextChanged(object sender, EventArgs e)
        {
            TextBox Sender = (TextBox)sender;
            if (Sender.Text == Sender.Attributes["OriginalValue"])
                Sender.ForeColor = System.Drawing.Color.Black;
            else
                Sender.ForeColor = System.Drawing.Color.Blue;
        }
    }
}

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    您好,我花了一些时间来编译您的代码,我想通了,只需将您的文本框更改更改为以下内容:

     void txtBox_TextChanged(object sender, EventArgs e)
            {
                TextBox Sender = (TextBox)sender;
                if (Sender.Text == Sender.Attributes["OriginalValue"])
                    Sender.ForeColor = System.Drawing.Color.Black;
                else
                {
                    Sender.ForeColor = System.Drawing.Color.Blue;
                    if (Session["MyData"] != null)
                    {
                        List<string> _ss = (List<string>)Session["MyData"];
                        //_ss.Find(a => a == Sender.Attributes["OriginalValue"]);
                        _ss.Remove(Sender.Attributes["OriginalValue"]);
                        _ss.Add(Sender.Text);
                    }
                }
            }
    

    欢迎您!

    【讨论】:

    • 您确定没有进行任何其他更改吗?当我尝试这个时,我仍然看到相同的结果。
    • 不,我没有 :) 仅此而已,如果您愿意,我可以将代码发送给您
    • 所以我做了这个改变,我仍然得到相同的结果。实际上,如果我再次单击其中一个按钮然后更改文本框中的值,则 TextChanged 事件不会触发!如果我对文本框进行另一项更改,则事件从那时起触发,直到再次单击按钮后的第一次更改。 (我认为您的事件每次都在触发?)
    【解决方案2】:

    尝试创建数据表。我会在“事件”上将您的 asp 表内容复制到数据表中,然后当您获得服务器响应时将其添加到数据表中。然后将数据表复制回您的 asp 表,然后重复……数据表可以像变量一样使用。

    或者尝试使用 cookie。

    【讨论】:

      【解决方案3】:

      尝试改变...

       protected void Page_Init(object sender, EventArgs e)
              {
                  LoadSessionData();
                  GenerateGrid(false);
              }
      

      到...

      protected override void OnLoadComplete(EventArgs e)
      {
           LoadSessionData();
           GenerateGrid(false);
       }
      

      根据您的描述,我相信您的值正在重置,因为页面生命周期在 ASP.NET 中的工作方式以及由于 ASP.NET 的怪异而在您的事件之前调用 page_init。上面的代码是我解决它的方法,我相信还有其他方法。

      【讨论】:

      • 这对我也不起作用。如果我将参数保留为 False,我会得到 2 行。如果我将其更改为 True,那么我将始终显示原始数据,因为我在页面加载后删除并重新创建了动态控件。 (我想如果我等待 OnLoadComplete,则在 ASP.NET 处理会话状态时不会创建动态控件。我不需要在 Init 事件中重新创建动态控件,以便它们在 Load 时存在触发?)
      【解决方案4】:

      好的,我现在可以正常工作了。 Wizpert 的回答为我指明了正确的方向......在发现 TextChanged 事件在值被错误地重置为原始值期间没有触发时,我突然想到在 Click 事件期间我正在调用 GenerateGrid(true )。这迫使删除现有行并添加新行。 (在生命周期的那个点删除和添加动态控件必须干扰 TextChange 事件处理程序。)由于 Click 事件在 Page Init 和 Page Load 之后触发,状态值已经写入文本框,我是覆盖它们。但是第二个文本框编辑并没有强制调用 GenerateGrid(true),因此状态值不再被覆盖。

      如果这听起来令人困惑,我深表歉意。我还在纠结这个。但我只想说我必须更改我的 GenerateGrid 方法以重用任何现有行而不是删除它们。 (如果它们不存在,例如从 Page Init 调用 GenerateGrid 时,则会添加它们。)所以这毕竟是一个页面生命周期问题。

      谢谢。

      【讨论】:

        猜你喜欢
        • 2011-02-07
        • 2011-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-06
        • 1970-01-01
        • 2011-06-07
        • 2010-11-02
        相关资源
        最近更新 更多