我正在開發一個原始爲Visual Studio網站項目的舊網站,並將其轉換爲Web應用程序以及其他工作。網站上的一個頁面使用GridView,並使用DataTable在代碼隱藏中設置DataSource。 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>
頁也有一個提交按鈕,並在_Click處理程序,代碼試圖搶Results.Rows
,然後以確定哪些行已被他們選中的複選框周圍挖。它根據選中的行進行後續處理。
- 舊的站點代碼沒有IsPostBack檢查,並且只在DataBind爲false時才調用它。
- 的頁面不定義任何的EnableViewState或ViewStateMode,這意味着他們都默認設置爲true,根據MSDN。
- 在母版頁或其他任何地方都沒有對DataBind的調用。
- 舊的站點代碼不會執行任何手動保存到ViewState字典。
- 令人驚訝的是,這個網站的生產版本實際上工作。
由於我一直在處理這個問題,我只找到線程和文章來討論GridView如何不實際使用ViewState,以及如何使用發送給用戶的數據,DataTable用作數據源必須手動插入的ViewState在後面的代碼等
我的工作已被轉換爲一個Web應用程序項目現場的版本,它的目標.NET 4.5。當我調試該網站並在Page_Load
或Submit_Click
中斷時,Results
GridView具有一個空數據源,並且Rows屬性具有0個計數。這似乎與目前關於GridView「如何工作」的傳統觀點一致。
我很清楚地知道,對於這個網站是幹什麼的,這是一個令人髮指的實現,並有更好的方法來做到這一點。然而,我最關心的是我無法找到任何關於舊版本如何工作的解釋。
難道在其歷史忽略其EnableViewState屬性某些時候GridView的變化?實際上,GridView上的EnableViewState是做什麼的?它可能是網站和Web應用程序項目之間的區別嗎?
這可能如何工作?
更新:根據伯特埃文斯例如頁面上,我嘗試了這種修改過的頁面。
<%@ 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;但是,在回發中,頁面加載和OnClick方法中的行計數均爲0。
只需查看頁面的HTML標記中的視圖狀態即可。打開和關閉啓用視圖狀態並查看差異。 – mason
你是說它在生產版本中有效,但不是在你的產品中? – Bert
@BertEvans是的 - 在某些方面,舊版本在回發處理期間管理從GridView的Rows屬性中提取數據,除了在數據層中劃分出一些SQL訪問權限之外,所有已更改的內容都將升級項目到Web應用程序(並可能使用更新的.NET版本)。 – bwerks