当EnableViewState =“false”时,ListView + ObjectDataSource SelectMethod被调用两次

时间:2010-11-29 23:08:43

标签: asp.net listview objectdatasource

注意:此问题已完全修改,因为我有一个更简单的示例。

我已经设置了一个只有ListViewObjectDataSource的示例页面。页面第一次出现(!IsPostBack)时,我的GetList方法被调用一次。在分页(IsPostBack)之后,GetList方法被调用两次 - 第一次使用旧的分页值,第二次使用新的值。

如果我在EnableViewState="true"上设置了ListView,那么GetList方法只会被调用一次。在我看来,ListView想要一个“初始状态”,它可以从ViewState获得,也可以通过重新运行该方法。

有没有办法在ListView上停用ViewState并阻止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; }
    }
}

3 个答案:

答案 0 :(得分:2)

打开ODS缓存。

<asp:ObjectDataSource ID="ODS" ... EnableCaching="true" />

这样,只有在需要新数据时才会调用GetList。回溯到已检索数据的页面将使用缓存版本,而不是调用GetList。

或者将DataPager移出ListView并设置PagedControlID属性。

答案 1 :(得分:0)

实际上你应该使用OnSelecting事件。

ObjectDataSource调用方法SelectMethod 两次

  1. 第一次获取数据。
  2. 下次获得点数。
  3. 所以我认为你必须实现OnSelecting事件

    <asp:ObjectDataSource ID="ODS" runat="server" SelectMethod="GetList" SelectCountMethod="GetListCount" 
        OnSelecting="ods_Selecting">
        TypeName="Website.Test" EnablePaging="true" /> 
    

    然后在ObjectDataSource尝试调用count方法时取消该事件。

     protected void ods_Selecting(object sender,
                    ObjectDataSourceSelectingEventArgs e)
     {
          if (e.ExecutingSelectCount)
          {
               //Cancel the event   
               return;
          }
    }
    

    您可以查看以下链接中提到的完整实施 http://www.unboxedsolutions.com/sean/archive/2005/12/28/818.aspx

    希望这有帮助。

答案 2 :(得分:0)

我有一个类似的问题,它根据浏览器的不同而有所不同。 IE单向和所有其他浏览器单向..可能与您没有相同的问题。

我这样解决了:

        protected void DropDownDataBound(object sender, EventArgs e)
    {
        // Issue with IE - Disable ViewState for IE browsers otherwhise the dropdown will render empty.
        DropDownList DDL = (DropDownList)sender;
        if (Request.Browser.Browser.Equals("IE", StringComparison.CurrentCultureIgnoreCase))
            DDL.ViewStateMode = System.Web.UI.ViewStateMode.Disabled;
        else
            DDL.ViewStateMode = System.Web.UI.ViewStateMode.Inherit;           
    }