2016-08-13 5 views
1

Я работаю над старым сайтом, созданным как проект веб-сайта 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.

+0

Просто посмотрите на состояние представления в разметке HTML на странице. Включите и выключите экран просмотра и просмотрите разницу. – mason

+0

Вы говорите, что это работает в производственной версии, но не в вашей? – Bert

+0

@BertEvans Да - как-то старая версия управляет извлечением данных из свойства Rows GridView во время обработки обратной обработки, и все, что я изменил, помимо вырезания некоторого доступа SQL к слою данных, обновляет проект к веб-приложению (и, возможно, с использованием более новой версии .NET). – bwerks

ответ

1

Благодаря Берт Эвансу и его странице примеров я в конечном итоге выделил проблему. Ошибка на самом деле в замечательном примере кода MSDN для UnityHttpModule, который объединяет Unity DI с ASP.NET. UnityHttpModule подробно описана в https://msdn.microsoft.com/en-us/library/ff664534(v=pandp.50).aspx.

В дополнение к тому, что на самом деле даже не компилируется, как указано в списке, класс прокладывает код DI в событии InitComplete, который выполняется перед загрузкой ViewState, как описано в этой статье: ASP.NET 4.0 GridView OnRowEditing events not firing when using Unity 2.0 http module. В моем случае, перемещение кода DI для выполнения на PreLoad фиксировало мою проблему.

И наконец, для полноты и для тех, у кого есть проблемы с MSDN Unity DI HttpModule, другой поток SO также предоставляет рабочий пример: ASP.NET Dependency Injection HTTP Module (MS Enterprise Library).

1

Databinding - это процесс перевода указанного источника данных для элемента управления в дерево управления, которое отображается на странице.Для GridView s, по существу, устанавливая свойство DataSource и вызывая метод DataBind, переводит IEnumerable или IEnumerable, извлеченный из другого источника, такого как DataSet или , в таблицу HTML с элементами управления, содержащими данные.

Каждый из элементов управления воспроизводимыми в ячейки таблицы поддерживает его собственный ViewState, так что, когда страница отправляется обратно на сервер, GridView перестраивает структуру управления и заселяет управление с данными в ViewState (или, скорее, , Страница инициирует перестройку структуры управления, и только GridView).

DataSource не сохраняется в ViewState, только состояние визуализированных элементов управления.

Отключение ViewState от GridView предотвращает его сохранение определенных элементов его собственного состояния, что предотвратит его возможность делать такие вещи, как разбиение на страницы и сортировку. Кроме того, если вы отключите ViewState на GridView и выполните обратную передачу (инициируйте событие на стороне клиента, которое отправляет страницу обратно на сервер), тогда GridView ничего не отобразит при повторной передаче страницы, поскольку EnableViewState наследуется, и дочерние элементы управления будут предотвращены для сохранения собственного состояния. Единственный способ получить GridView с отключенным ViewState, чтобы отображать данные снова после того, как сообщение было отправлено повторно для передачи данных (вызов DataBind снова с источником данных, который имеет данные) или для включения вручную ViewState на дочерних элементах управления внутри GridView с отключенным ViewState. Вы упомянули, что DataBind на странице, над которой вы работаете, охраняются с помощью !IsPostback, поэтому он привязан только к начальной загрузке страницы.

Я ничего не знаю, так как GridView в один момент времени сохранил DataSource, я считаю, что так оно и всегда работало.

+0

В конечном итоге проблема оказалась Microsoft UnityHttpModule от MSDN, но я поддержал ваши ответы как благодарность за вашу помощь! Я бы не понял этого без этого. – bwerks

+0

@bwerks Я рад, что вы это поняли. Я скопировал вашу модификацию моей примерной страницы в свою коробку, и она работала так, как ожидалось, поэтому я не мог понять, как помочь в будущем. Приятно найти хотя! – Bert