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

本文关键字:问题 NET 会话状态 ASP | 更新日期: 2023-09-27 18:16:58

我有一个问题,我认为是一个会话状态问题,但我在弄清楚什么是错误的损失。我有一个示例项目来说明这个问题。(代码如下)我有2个按钮。每个都用一些唯一的数据填充一个List,然后使用该数据向表中添加一行。该行包含文本框,以便用户可以编辑数据。(对于我的示例,没有更新按钮来持久化数据。)要在VS2010中重现这个问题,请创建一个新的"ASP. exe"。. NET Web Application"项目,并将aspx代码和c#代码复制/粘贴到Default中。

  • 按下DataSet 1按钮,网格应该填充1行。
  • 编辑其中一个文本框中的数据并关闭文本框。(新输入的文本应保留,字体应为蓝色。这就是我想要发生的。
  • 现在点击任意一个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;
        }
    }
}

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

你好,我花了一些时间来编译你的代码,我发现了,只要把你的文本框更改为以下内容:

 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);
                }
            }
        }

你的欢迎!

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

试着改变…

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

……

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

根据你的描述,我相信你的值正在重置,因为页面生命周期如何在ASP中工作。净,这是page_init被调用之前,你的事件由于ASP。净诡诈。上面的代码是我如何处理它的,我相信还有其他的方法。

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

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

谢谢。