c# - Textbox.Text 的值错误

标签 c# asp.net

我有一个列出当前项目的页面,如果您选择其中一个项目,它会加载带有参数的同一页面并显示属于该项目的用户。由于某种原因,有时(取决于项目)会在用户名所在的文本框中显示项目名称。

    protected void Page_Load(object sender, EventArgs e)
    {
        var dbProxy = new DatabaseProxy();

        // No parameter, show project list
        if (this.Request.QueryString["ProjectID"] == null)
        {
            var user = new UserContainer();
            user.LoadUser(HttpContext.Current.User.Identity.Name);

            List<ProjectContainer> projects = dbProxy.GetProjects(user.UserID, true);

            foreach (ProjectContainer project in projects)
            {
                var linkButton = new Button {Text = project.ProjectName};
                this.ProjectsPanel.Controls.Add(linkButton);
            }
        }
        // We have a parameter, show users for project
        else
        {
            int projectId = int.Parse(this.Request.QueryString["ProjectID"]);
            this.LoadUsers(projectId);
        }
    }

LoadUsers 函数:

    private void LoadUsers(int projectId)
    {
        var databaseProxy = new DatabaseProxy();
        List<UserContainer> users = databaseProxy.GetUsersByProject(projectId);

        foreach (UserContainer user in users)
        {
            var txtUsername = new TextBox();
            txtUsername.Text = user.Username; // <- Shows projectname!
            var txtUsername2 = new TextBox();
            txtUsername2.Text = user.Username; // <- Shows username!

            this.UserPanel.Controls.Add(txtUsername);
            this.UserPanel.Controls.Add(txtUsername2);
        }
    }

HTML 代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EditUsers.aspx.cs" Inherits="xxx.EditUsers1" MasterPageFile="PageStructure.Master" %>

<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="ContentPlace">
    <asp:Panel ID="Panel1" runat="server" style="padding-left: 25px">
        <div style="margin-bottom: 50px">
            <asp:Label ID="lblHeader" runat="server" Text="Benutzer verwalten" CssClass="PageHeader"></asp:Label>
        </div>
        <asp:Panel ID="UserPanel" runat="server"></asp:Panel>
        <asp:Panel ID="ProjectsPanel" runat="server"></asp:Panel>
    </asp:Panel>
</asp:Content>

母版页仅包含页眉和页脚以及其他页面的一些 JavaScript。

输出:

/image/p49jh.png

用户变量包含正确的值,并且在 LoadUsers 之后没有任何反应。我什至可以添加一个空标签作为第一个元素,然后它将在第一个文本框中显示正确的用户名!我不知道为什么,但看起来它确实希望在我添加的第一个元素中包含项目名称。

示例它是如何工作的:

    private void LoadUsers(int projectId)
    {
        var databaseProxy = new DatabaseProxy();
        List<UserContainer> users = databaseProxy.GetUsersByProject(projectId);

        foreach (UserContainer user in users)
        {
            var lbl = new Label();
            lbl.Text = ""; <- Stays invisible!
            var txtUsername = new TextBox();
            txtUsername.Text = user.Username; // <- Shows username!
            var txtUsername2 = new TextBox();
            txtUsername2.Text = user.Username; // <- Shows username!

            this.UserPanel.Controls.Add(lbl);
            this.UserPanel.Controls.Add(txtUsername);
            this.UserPanel.Controls.Add(txtUsername2);
        }
    }

我想我可以找到一种解决方法,比如将其拆分为两个不同的 Web 表单,但我仍然想知道为什么我得到错误的值。

最佳答案

该问题是由控件的 View 状态不同步引起的。

在 ASP.NET 中,每个表单控件都有一个 View 状态,用于跟踪输入的值,以便在回发后重新加载页面时,它可以自动将以前的值填充到每个表单控件中。通常这会很好地工作,并且通常是期望的行为。但是,在某些情况下(例如这种情况),控件是动态生成的,并且它们的值在从回发返回后发生更改,那么它们的 View 状态最终将覆盖这些值,从而导致问题。

要解决此问题,请禁用动态生成的控件的回发,如下所示:

foreach (UserContainer user in users)
{
    var txtUsername = new TextBox();
    txtUsername.EnableViewState = false;
    txtUsername.Text = user.Username; // <- Shows projectname!

    var txtUsername2 = new TextBox();
    txtUsername2.EnableViewState = false;
    txtUsername2.Text = user.Username; // <- Shows username!

    this.UserPanel.Controls.Add(txtUsername);
    this.UserPanel.Controls.Add(txtUsername2);
}

或者在每次生成时为每个控件分配不同的 ID,这样该控件就永远不会与 View 状态中保存的数据的 ID 匹配,如下所示:

foreach (UserContainer user in users)
{
    var txtUsername = new TextBox();
    txtUsername.ID = Guid.NewGuid().ToString("N");
    txtUsername.Text = user.Username; // <- Shows projectname!

    var txtUsername2 = new TextBox();
    txtUsername2.ID = Guid.NewGuid().ToString("N");
    txtUsername2.EnableViewState = false;
    txtUsername2.Text = user.Username; // <- Shows username!

    this.UserPanel.Controls.Add(txtUsername);
    this.UserPanel.Controls.Add(txtUsername2);
}

警告:如果您使用上述任一方法,则在回发或表单提交期间将不会发送回控件的值。因此,用户在任何这些控件中输入的值都将丢失。为了避免此问题,请在表单提交时使用 JavaScript 将这些值复制到隐藏控件(不是动态生成的)。或者只是不使用动态生成的控件(如果可能的话)。

有关 View 状态与动态控件的更多信息,请查看:http://msdn.microsoft.com/en-us/library/hbdfdyh7%28v=vs.100%29.aspx

关于c# - Textbox.Text 的值错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23468405/

相关文章:

c# - 从数组中删除元素。指数。 C#。列表<双>

c# - 在 SharePoint 应用程序页面 .aspx 上使用模型

asp.net - 导航菜单 - 渲染分隔管道字符

c# - 在 VS2010 中更改 Web 项目中的输出路径

C# 无法在 asp.net 中读取 XML 文件

c# - 将 javascript 数组解析为 C# 对象列表

c# - .NET 编译器优化

c# - 从后面生成文本框控件 "C#"

c# - .NET 包含的哪些哈希算法适用于密码哈希?

.net - 如何抓取网站,客户端或服务器端?