Почему в форме публикуются значения не тех, которые отправлены пользователями?

Я использую веб-формы Asp.net. У меня есть форма со столом и полем со списком. Таблица изменяется по мере изменения выбранного элемента в поле со списком. Поле со списком является элементом управления asp.net, и я установил autopostback = true. Таблица также является элементом управления asp.net, и все ячейки таблицы создаются / отображаются на стороне сервера.

Пользователи будут вводить значения в таблицу и отправлять их на сервер.

Проблема, которую я обнаружил, состоит в том, что когда пользователь изменяет выбранный элемент поля со списком, таблица изменяется и веб-страница отображается правильно. Затем пользователь вводит некоторые значения и нажимает кнопку "Отправить". Со стороны сервера значение, которое я получаю, является значениями таблицы по умолчанию, а не пользовательскими данными. Если пользователь отправляет снова, серверная сторона может получить пользовательские входные данные.

Вот код, который я пишу, чтобы воспроизвести эту проблему. Я создаю проект веб-формы по умолчанию, добавляю новый веб-сайт, от которого наследуется мастер сайта. Для воспроизведения выполните следующие действия: 1. выберите один переключатель 2. отправьте, и вы увидите текст о своем выборе в верхней части страницы. 3. измените выбор поля со списком 4. выберите другой переключатель 5. подтвердите, и вы найдете ошибку. 6. Повторите 4 и 5, вы найдете правильный текст.

 <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="PostBackUsingMasterPage.aspx.cs" Inherits="WebFormBug.PostBackUsingMasterPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">

    <asp:DropDownList ID="comboBox" runat="server" AutoPostBack="true" OnSelectedIndexChanged="UpdateTable">
                <asp:ListItem>Apple</asp:ListItem>
                <asp:ListItem>Beet</asp:ListItem>
                <asp:ListItem>Citron</asp:ListItem>

    </asp:DropDownList>
    <asp:Label ID="userInput" runat="server"></asp:Label>
    <asp:Table runat="server" ID="testTable"> </asp:table>
    <asp:Button ID="submit" runat="server" Text="Submit for validation" OnClick="SubmitButton_Click" />
</asp:Content>

Aspx.cs похож на это

using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace WebFormBug
{
    public partial class PostBackUsingMasterPage : Page
    {
        private string _scope; 
        protected void Page_Load(object sender, EventArgs e)
        {
            _scope = comboBox.SelectedValue ?? "Apple";
            PopUpTable(_scope);
        }

        private void PopUpTable(string item)
        {
            testTable.Rows.Clear();
            var row = new TableRow();
            row.Cells.Add(new TableCell {Text = item});
            row.Cells.Add(AddRadioButtons(item));
            testTable.Rows.Add(row);
        }

        private TableCell AddRadioButtons(string name)
        {
            var cell = new TableCell();
            var radioButtons = new HtmlInputRadioButton[5];
            for (var i = 0; i < 3; i++)
            {

                radioButtons[i] = new HtmlInputRadioButton { Name = name, Value = name + " " + i };

                cell.Controls.Add(radioButtons[i]);
                var label = new Label { Text = name + " " + i };
                cell.Controls.Add(label);
            }
            return cell;
        }

        protected void UpdateTable(object sender, EventArgs e)
        {
            PopUpTable(comboBox.SelectedValue);
        }

        protected void SubmitButton_Click(object sender, EventArgs e)
        {
            int valueIndex = 1;
            for (int i = 0; i < testTable.Rows.Count; i++)
            {
                var row = testTable.Rows[i];
                string inputValue = null, inputName = null;
                foreach (var ctrl in row.Cells[valueIndex].Controls)
                {
                    if (ctrl is HtmlInputRadioButton)
                    {
                        var radioInput = (HtmlInputRadioButton) ctrl;
                        if (!radioInput.Checked) continue;
                        inputValue = radioInput.Value;
                        inputName = radioInput.Name;
                        break;
                    }
                }
                if (inputName != null && inputValue != null)
                {
                    userInput.Text = inputName + " " + inputValue;
                }
            }

        }
    }
}

3 ответа

Решение

Знание подготовки ASP.NET WebForm: динамически добавленные данные таблицы отсутствуют в форме post. Таблица asp.net при добавлении строк динамически не сохраняется после обратной передачи. Это ваш пример - вы создаете данные таблицы динамически.

Решение для публикации данных динамической таблицы состоит в том, чтобы заново создать данные формы в каждом сообщении обратно (и должно быть ТОЛЬКО в) на странице метода Load. и ваш образец делает это (PopUpTable метод всегда вызывается в Page_Load).

Тем не менее, в вашем коде Page_Load это не единственное место, где делают воссоздание таблицы, но и в OnSelectedIndexChanged что приводит к очистке данных вашей таблицы. На самом деле, вам не нужно регистрировать это событие.

Итак, решение (извините за прикрепление кода в качестве изображения, но я обнаружил, что прикрепление большого сегмента кода очень сложно отформатировать):

  1. Удалить OnSelectedIndexChangedвведите описание изображения здесь
  2. Измените код, как показано ниже:

введите описание изображения здесь

Попробуй это:
при загрузке страницы:

if(!IsPostBack)
{
    // set data to table
}

Я предполагаю, что у вас есть панель обновления, с помощью которой изменение выбранного индекса в раскрывающемся списке обновляет радиокнопки. Вы можете попробовать изменить обработчик событий для выпадающего списка на

protected void UpdateTable(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        PopUpTable(comboBox.SelectedValue);
    }
}
Другие вопросы по тегам