ASP.NET会话状态&回发问题

时间:2014-08-06 15:11:27

标签: c# asp.net

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

  • 按DataSet 1按钮,网格应填充1行。
  • 在其中一个文本框中编辑数据,然后从文本框中选择标签。 (新输入的文本应该是remian,字体应该是蓝色。这就是我想要发生的事情。)
  • 现在单击任一DataSet按钮以重置List并刷新表。 编辑其中一个文本框中的数据,然后选中文本框。 (紧接着,框中的文本会刷新回原来的值。但这只会发生一次。如果现在编辑任一文本框,它将正常工作。)
  • 这是可重复的...按下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;
        }
    }
}

4 个答案:

答案 0 :(得分: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);
                }
            }
        }

欢迎你!

答案 1 :(得分:0)

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

或尝试使用Cookie。

答案 2 :(得分:0)

尝试更改......

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

要...

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

根据您的描述,我认为您的价值正在重置,因为页面生命周期在ASP.NET和&amp ;;由于ASP.NET的怪癖,因此在事件发生前调用page_init。以上代码是我如何解决它,我也确定还有其他方法。

答案 3 :(得分:0)

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

如果这听起来令人困惑,我道歉。我仍然围绕着这个问题。但足以说我必须更改我的GenerateGrid方法以重用任何现有行而不删除它们。 (如果它们不存在,就像从Page Init调用GenerateGrid那样,那么它们就会被添加。)所以这毕竟是页面生命周期问题。

谢谢。