【问题标题】:How to store/restore table with dynamic elements in view state in c# asp web aplication如何在c#asp web应用程序中存储/恢复具有视图状态的动态元素的表
【发布时间】:2017-05-19 15:04:35
【问题描述】:

我不熟悉具有动态内容的网络应用程序的概念。 我正在创建一个简单的应用程序,它从数据库中获取信息(测试步骤)并向表中添加行(每行包含两个标签、两个单选按钮和文本字段)。

它的工作原理是这样的: 1.我有一个带有文本框和按钮的页面, 2.我输入测试ID来检索测试步骤,然后点击提交按钮 3. 根据步骤数,我为每个步骤在表格中添加一行,因此我的表格如下所示:

[Label.text="Step1"][RadioButtonPass][RadioButtonFail][Label.Text="Comment:"][TextBox]
[Label.text="Step2"][RadioButtonPass][RadioButtonFail][Label.Text="Comment:"][TextBox]
[Label.text="Step3"][RadioButtonPass][RadioButtonFail][Label.Text="Comment:"][TextBox]
etc.
  1. 当用户按下每个单选按钮时,他可以单击 submitResult 按钮并将数据发送到 db。

页面生成正确,但我在处理动态内容时遇到问题,因为当我点击 submitResult 按钮时,表格再次为空(此时 submitResult 按钮什么也不做)。我读过它,我认为我需要将表存储到视图状态中。我该怎么做?

我试图将表格保存到

ViewState[table.ID] = table;

在PopulateTable方法的最后,然后在里面恢复

protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                if (ViewState[TableForMethods.ID] != null)
                {
                    TableForMethods = (Table)ViewState[TableForMethods.ID];
                }
    }
}

但这不起作用。

我的代码如下所示:

*.aspx

<body style="height: 510px">
    <form id="form1" runat="server">
         <p>
            Put test case ID and submit
        </p>
        <asp:TextBox ID="TextBoxId" runat="server">1804673290</asp:TextBox>
        <asp:Button ID="ButtonRetriveId" runat="server" OnClick="ButtonSubmitId_Click" Text="Submit" Width="81px" />
        <p>
            &nbsp;
        </p>
         <p>
            <asp:Label ID="LabelMethods" runat="server"></asp:Label>
        </p>
        <p>
            <asp:Table ID="TableForMethods" runat="server">
            </asp:Table>
        </p>
        <div style="text-align: right">
            <asp:Button ID="ButtonSubmitResults" runat="server" Text="Submit result" OnClick="ButtonSubmitResults_Click" Visible="False" />
        </div>

        <div style="text-align: right; position: absolute; bottom: 0px">
        <asp:Label ID="LabelStatus" runat="server"></asp:Label>
        </div>

    </form>

    <script>
        var trPassArray = $("tr input[id*='RadioButtonPass']").click(function () {
            this.closest("tr").setAttribute("bgcolor", "yellowgreen");
            console.log("zmien na green");
            console.log(closest("tr"));
        });

        var trFailArray = $("tr input[id*='RadioButtonFail']").click(function() {
            this.closest("tr").setAttribute("bgcolor", "orangered");
            console.log("zmien na red");
            console.log(this.closest("tr"));
        });

        console.log(trPassArray);
        console.log(trFailArray);
    </script>
</body>

*.aspx.cs

     protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void ButtonSubmitId_Click(object sender, EventArgs e)
        {
           this.PopulateTable(TableForMethods, value);
           ButtonSubmitResults.Visible = true;
        }

    protected void ButtonSubmitResults_Click(object sender, EventArgs e)
    {
    }

   private void PopulateTable(Table table, string value)
        {
            string[] sep = { "<br>" };
            var words = value.Split(sep, StringSplitOptions.RemoveEmptyEntries);

            for (int iterator = 1; iterator <= words.Count(); iterator++)
            {
                var tRow = new TableRow { ID = "Row" + iterator };
                table.Rows.Add(tRow);

                var tCell = new TableCell();

                var myLabel = new Label
                {
                    Text = words[iterator - 1],
                    ID = "Label " + iterator
                };

                var radiobuttonPass = new RadioButton
                {
                    Text = "Pass ",
                    ID = "RadioButtonPass " + iterator,
                    GroupName = "passFailGroup" + iterator,
                };

                radiobuttonPass.CheckedChanged += passRadioButton_CheckedChanged;

                var radiobuttonFail = new RadioButton
                {
                    Text = "Fail ",
                    ID = "RadioButtonFail " + iterator,
                    GroupName = "passFailGroup" + iterator,
                };

                radiobuttonFail.CheckedChanged += failRadioButton_CheckedChanged;

                var upPassFail = new UpdatePanel { UpdateMode = UpdatePanelUpdateMode.Conditional };
                upPassFail.ContentTemplateContainer.Controls.Add(radiobuttonPass);
                upPassFail.ContentTemplateContainer.Controls.Add(radiobuttonFail);

                var passTrigger = new AsyncPostBackTrigger
                {
                    ControlID = radiobuttonPass.ID,
                    EventName = "CheckedChanged"
                };
                upPassFail.Triggers.Add(passTrigger);

                var failTrigger = new AsyncPostBackTrigger
                {
                    ControlID = radiobuttonFail.ID,
                    EventName = "CheckedChanged"
                };
                upPassFail.Triggers.Add(failTrigger);

                var labelComment = new Label
                {
                    Text = " Comment:",
                    ID = "LabelComment " + iterator.ToString()
                };

                TextBox textBoxComment = new TextBox { ID = "TextBoxComment " + iterator.ToString() };

                tCell.Controls.Add(myLabel);
                tCell.Controls.Add(radiobuttonPass);
                tCell.Controls.Add(radiobuttonFail);
                tCell.Controls.Add(labelComment);
                tCell.Controls.Add(textBoxComment);
                tRow.Cells.Add(tCell);
            }
        }

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    您尝试执行的操作将行不通。 ViewState 被服务器应用程序用来存储请求之间的信息。

    • 在页面加载或回发过程中,服务器会修改页面或其控件的状态
    • 当您回帖时,如果没有办法“记住”所做的事情,所有这些更改都会丢失。这就像再次加载页面一样。
    • ASP.NET 通过在表单字段 (ViewState) 中写入有关控件的详细信息来解决此问题。这样每次回发时,您都会将数据发送回服务器,告诉它页面和控件的状态是什么,因此它可以重新创建它。

    您正在对客户端上的 HTML 进行更改。此时页面已呈现,包括ViewState。它只跟踪服务器的 更改,而不是客户端上发生的任何事情。所以服务器永远不会知道这些变化发生了。

    有几种方法可以解决这个问题(不止两种,但这些是显而易见的。)

    1. 为了修改该表,无论发生什么变化,都必须在服务器上进行。如果用户与某物交互,请回发到服务器。服务器修改表,并假设为表启用了ViewState,这些更改已写入ViewState 并保持不变。
    2. 避免回发。如果没有服务器控件,那么在页面加载后它的行为就像一个普通的 HTML 页面,你可以在客户端做任何你想做的事情。
    3. 这有点混乱:将客户端更改存储在客户端上。当您更新客户端上的表时,您可以将其存储在localStorage 中。当页面刷新时,您可以拥有一个客户端脚本来检查localStorage 并恢复您存储在那里的任何客户端内容。可以把它想象成ViewState,但恰恰相反。 ViewState 存储往返之间的服务器端数据。 localStorage 存储往返之间的客户端数据。问题是,在某些回发时,您可能会完全更改表格(例如新数据或其他内容),并且您必须有一种方法来区分它,以便在这种情况下您不会从 localStorage 刷新它.

    将 WebForms 与客户端代码混合使用可能有点令人沮丧。我们开始学习所有这些简洁的客户端工具,但它们并不总是能很好地适应 WebForms 的行为。客户端代码想要更改页面上的内容。 WebForms 想要刷新整个页面。

    如果可能的话,我个人会选择一或二,而不是试图杂交两者的行为。

    【讨论】:

    • 您好,感谢您的详细回答,选项 1 看起来最好。我该怎么做?我在 PopulateTable 方法的末尾添加 ViewState[table.ID] = table 但更改不是持久的,我做对了吗? “加载”状态的正确方法是什么?
    猜你喜欢
    • 2012-06-11
    • 2016-12-18
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多