Примечание: Этот вопрос был полностью изменен сейчас, когда у меня есть более простой пример.ListView + ObjectDataSource SelectMethod вызывается дважды, когда EnableViewState = "false"
Я установил образец страницы, который имеет только ListView
и ObjectDataSource
. При первой странице страницы (!IsPostBack
) мой метод GetList
вызывается один раз. После подкачки (IsPostBack
) метод GetList
вызывается дважды - первый раз со старыми значениями поискового вызова и второй раз с новыми значениями.
Если я установил EnableViewState="true"
на ListView
, то метод GetList
вызывается только один раз. Мне кажется, что ListView
хочет «начальное состояние», которое оно либо получает от ViewState
, либо путем повторного запуска метода.
Есть ли способ отключить ViewState на ListView
, а также не допустить, чтобы SelectMethod
был вызван дважды?
ASPX страница:
<asp:ListView ID="TestListView" runat="server" DataSourceID="ODS" EnableViewState="false">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
<asp:DataPager ID="TestPager" runat="server" PageSize="10">
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
<div><%# Eval("Title") %></div>
</ItemTemplate>
</asp:ListView>
<asp:ObjectDataSource ID="ODS" runat="server" SelectMethod="GetList" SelectCountMethod="GetListCount"
TypeName="Website.Test" EnablePaging="true" />
ASPX кода позади:
namespace Website
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public IList<DataItem> GetList(int maximumRows, int startRowIndex)
{
return GetListEnumerable().Skip(startRowIndex).Take(maximumRows).ToList();
}
public IEnumerable<DataItem> GetListEnumerable()
{
for (int i = 0; i < 100; i++)
{
yield return new DataItem { Title = i.ToString() };
}
}
public int GetListCount()
{
return 100;
}
}
public class DataItem
{
public string Title { get; set; }
}
}
Я думал кэширование, но в моем случае есть бесконечные возможности параметров, поэтому я хотел бы, чтобы продолжительность кэша быть очень мала (скажем, 10 секунд вершины). Если пользовательские страницы после 10 секунд, это будет еще двойной запрос, который немного замедляет страницу. Включение режима ViewState было бы лучше. Перенос DataPager из ListView не помог - он все еще удваивается. Мне интересно, могу ли я прямо или косвенно (через Reflection) установить `BaseDataBoundControl.RequiresDataBinding`. – 2010-12-01 16:08:29
Я попытался установить `RequiresDataBinding` в false через Reflection и это предотвращает двойной запрос. Однако это первый запрос (до пейджинга), поэтому я не могу его использовать. Наверное, сейчас я оставлю ViewState. – 2010-12-01 16:17:34
Я не думал о параметрах. Я не знаю, как кэширование реализовано, когда дело доходит до этого. Тем не менее, перемещение пейджера из списка привело к хитрости для меня. Думаю, это не надежное решение. RequiresDataBinding получает избыток в нескольких местах. Если позволит время, вы можете попытаться создать свой собственный элемент управления из ListView и обработать как CreateChildren, так и RequiresDataBinding. Тогда всегда есть ViewState ... :) – Ruslan 2010-12-02 21:07:33