#asp.net #html-table
#asp.net #html-таблица
Вопрос:
У меня есть две HTML-таблицы, первая заполняется на стороне сервера через записи в базе данных, а вторая заполняется через клиентский Javascript, который позволяет пользователю динамически добавлять строки и вводить данные через текстовые поля ввода.
Кнопка в конце моей формы отвечает за передачу данных из обеих в серверную часть SQL Server. Проблема в обратной передаче, я не могу прочитать из этих таблиц. Это относится как к управляемой таблице на стороне клиента, так и к управляемой таблице на стороне сервера.
<table style="display: none; width: 100%" runat="server" id="tblWebOrderArbitraryContacts" class="borderBottomStyle">
<table runat="server" id="recipientTable" style="display: block; width: 100%" class="borderBottomStyle"></table>
//the problem is the row count is always zero, regardless of what data is in it
if(tblWebOrderArbitraryContacts.Rows != null amp;amp; tblWebOrderArbitraryContacts.Rows.Count > 0)
{
//go through automatically derived (from integrations) contacts
foreach (HtmlTableRow row in tblWebOrderArbitraryContacts.Rows)
{
...
Комментарии:
1. Нет, логика повторного связывания находится внутри условного оператора, это было первое, что я проверил. Я также попробовал Page. FindControl безрезультатно (он находит элемент управления нормально, но строки по-прежнему пусты).
2. Проверьте количество строк сразу после добавления?
Ответ №1:
Объяснение
Проблема в том, что при отправке запроса на сервер для этой страницы создается новый экземпляр страницы вместе со всеми элементами управления, определенными в вашем aspx-файле. Этот новый экземпляр страницы и дочерних элементов управления запускается без данных.
Когда вы отправляете запрос «post» обратно на сервер («обратная отправка»), страница просматривает коллекцию форм запроса (данные из тегов <input>, отправленных браузером) и пытается обновить веб-элементы управления на странице данными, найденными в этой коллекции форм.
Кроме того, но помимо этого, элементы управления с поддержкой viewstate могут пытаться заполнить себя на основе данных, найденных в viewstate, оставленных другим экземпляром того же элемента управления из предыдущего запроса.
В частности, если вы посмотрите на TextBox webcontrol, вы можете увидеть, что он реализует интерфейс IPostBackDataHandler. Что происходит, так это то, что в начале запроса страница просматривает все значения в коллекции форм, отправленной запросом. Когда страница находит значение в коллекции форм, ключ которого соответствует идентификатору элемента управления TextBox, страница может применить это обновленное значение к этому элементу управления TextBox, используя метод LoadPostData интерфейса IPostBackDataHandler.
Похоже, что вы добавляете несколько строк данных в таблицу и отправляете их все обратно на сервер за один раз. Вы можете это сделать, но проблема в том, что на вашей странице нет элементов управления, которые могли бы выступать в качестве целевых объектов для этих данных. В частности, вам нужно назначить name
атрибут ваших тегов <input>, чтобы данные были отправлены на сервер, но что бы вы указали в качестве значения name
атрибута? Это не будет соответствовать элементу управления на вашей странице. Кроме того, если вы отправляете несколько строк одновременно, как бы вы отличили одну от другой?
Возможное решение
Предположим, что ваша страница после манипуляций с javascript и пользовательского ввода выглядит примерно так:
<table>
<thead><tr></th>First Name</th><th>Last Name</th></tr></thead>
<tbody>
<tr><td><input name="FirstName[0]" value="John" /></td><td><input name="LastName[0]" value="Smith" /></td></tr>
<tr><td><input name="FirstName[1]" value="Jane" /></td><td><input name="LastName[1]" value="Doe" /></td></tr>
<tr><td><input name="FirstName[2]" value="Spider" /></td><td><input name="LastName[2]" value="Man" /></td></tr>
</tbody>
</table>
В вашем исходном коде во время обратной передачи вы можете получить доступ к этим данным, используя такой код, как следующий:
string firstName = Request.Form["FirstName[0]"];
string lastName = Request.Form["LastName[0]"];
Вы также могли бы сделать что-то вроде этого:
int index = 0;
bool dataFound;
do
{
dataFound = false;
string firstName = Request.Form["FirstName[" index "]"];
if (firstName != null)
dataFound = true;
string lastName = Request.Form["LastName[" index "]"];
if (lastName != null)
dataFound = true;
// do something with firstName and lastName ...
index ;
} while (dataFound);
Ответ №2:
Я полагаю, что проблема с изменениями на стороне вашего клиента заключается в том, что ваша таблица ничего не добавляет к данным post формы. Вы манипулируете разметкой на клиенте, но сама разметка — это не то, что отправляется обратно, публикуются только входные элементы и их значения. Попробуйте добавить скрытый ввод и записать изменения на стороне клиента, чтобы данные были отправлены обратно на сервер. Затем на стороне сервера вы можете проанализировать содержимое поля ввода, чтобы определить, какие изменения были внесены.
Я подозреваю, что у вас аналогичная проблема с вашей таблицей, которая заполняется с помощью серверного кода. Если вы не сохраняете запись о ваших изменениях в объявленной разметке где-либо (viewstate, session и т.д.), То сервер понятия не имеет, что было сгенерировано предыдущим запросом, и возвращается к объявленной разметке.
Посмотрите на некоторые статьи о динамическом объявлении элементов управления для более глубокого объяснения. https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx#postadlink дает довольно хороший обзор того, что происходит, хотя используемые методы и примеры немного устарели.