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;
}
}
}
你好,我花了一些时间来编译你的代码,我发现了,只要把你的文本框更改为以下内容:
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时,则添加它们。)所以这毕竟是一个页面生命周期问题。
谢谢。