Я работаю над старым сайтом, созданным как проект веб-сайта Visual Studio, и который я конвертирую в веб-приложение в дополнение к другой работе. Одна страница на сайте использует GridView и устанавливает DataSource в кодировке с использованием DataTable. GridView предоставляет пару BoundFields, а также один TemplateField, в котором есть флажок. GridView настроен на использование EnableViewState.Был ли Asp.net GridView когда-либо способным использовать ViewState?
<asp:GridView ID="Results" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" EnableViewState="true">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:BoundField DataField="Type" HeaderText="Type"/>
<asp:BoundField DataField="ProcessDate" HeaderText="Process Date" />
<asp:BoundField DataField="Classification" HeaderText="Classification" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:TemplateField HeaderText="Notify?" ItemStyle-HorizontalAlign="Center">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" onclick="EnableSubmit(this);" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" onclick="EnableSubmit(this);" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
На этой странице также есть кнопка Submit, и в обработчике _Click, код пытается захватить Results.Rows
, а затем копает вокруг для того, чтобы определить, какие строки их флажки проверены. Он выполняет свою последующую обработку на основе проверенных строк.
- Старый код сайта проверяет IsPostBack и вызывает только DataBind, когда он является ложным.
- Страница не определяет EnableViewState или ViewStateMode, что означает, что оба они по умолчанию соответствуют true, согласно MSDN.
- Нет вызова DataBind на главной странице или что-то еще.
- Старый код сайта не содержит никакого руководства, сохраняющегося в словаре ViewState.
- Удивительно, что производственная версия этого сайта фактически работает.
Поскольку я работал над этим, я нашел только темы и статьи, обсуждая, как GridView фактически не использует ViewState, и как использовать данные, отправленные пользователю, DataTable, используемый как DataSource должен быть вставлен вручную в ViewState в коде позади и т. Д.
Версия сайта, над которым я работаю, была преобразована в проект веб-приложения и предназначена для .NET 4.5. Когда я отлаживаю сайт и перехожу в Page_Load
или Submit_Click
, Results
GridView имеет нулевой источник данных, а свойство Rows имеет счет 0. Это, похоже, согласуется с существующей общепринятой мудростью относительно того, как работает GridView.
Я хорошо знаю, что для того, что делает этот сайт, это отвратительная реализация, и есть намного лучшие способы сделать это. Однако меня больше всего беспокоит то, что я не могу найти никаких объяснений относительно того, как работает старая версия.
Сменился ли GridView в какой-то момент его истории, чтобы игнорировать его свойство EnableViewState? Что делает EnableViewState на GridView на самом деле? Разве это может быть разница между проектами веб-приложений и веб-приложений?
Как это возможно работать?
ОБНОВЛЕНИЕ: на основе страницы примера Берт Эванса я опробовал эту измененную страницу.
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public class Thing
{
public int ID { get; set; }
public string Name { get; set; }
}
IEnumerable<Thing> Things
{
get
{
var things = new List<Thing>();
things.Add(new Thing { ID = 1, Name = "One" });
things.Add(new Thing { ID = 2, Name = "Two" });
things.Add(new Thing { ID = 3, Name = "Three" });
things.Add(new Thing { ID = 4, Name = "Four" });
things.Add(new Thing { ID = 5, Name = "Five" });
return things;
}
}
void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ThingGridView.DataSource = Things;
ThingGridView.DataBind();
}
pageLoadLabel.Text = string.Format("On page Load, row count: '{0}'", ThingGridView.Rows.Count);
}
void OnClickMe(object sender, EventArgs e)
{
onClickLabel.Text = string.Format("On click, row count: '{0}'", ThingGridView.Rows.Count);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView runat="server" ID="ThingGridView">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name" />
</Columns>
</asp:GridView>
</div>
<asp:Button runat="server" ID="ThingButton" Text="Click Me!" OnClick="OnClickMe" />
<asp:Label runat="server" ID="onClickLabel" Text="[set on click]" />
<asp:Label runat="server" ID="pageLoadLabel" Text="[set on page load]" />
</form>
</body>
</html>
Единственные отличия - это метки, которые распечатывают количество строк в теле страницы. При выполнении этой страницы. первый вызов Page_Load выводит число строк 5 на страницу; однако в postback количество строк равно 0 и при загрузке страницы, и в методе OnClick.
Просто посмотрите на состояние представления в разметке HTML на странице. Включите и выключите экран просмотра и просмотрите разницу. – mason
Вы говорите, что это работает в производственной версии, но не в вашей? – Bert
@BertEvans Да - как-то старая версия управляет извлечением данных из свойства Rows GridView во время обработки обратной обработки, и все, что я изменил, помимо вырезания некоторого доступа SQL к слою данных, обновляет проект к веб-приложению (и, возможно, с использованием более новой версии .NET). – bwerks