开发者

ListView + ObjectDataSource SelectMethod called twice when EnableViewState="false"

开发者 https://www.devze.com 2023-01-28 01:26 出处:网络
Note: This question has been completely modified now that I have a simpler example. I have set up a sample page which only has a ListView and ObjectDataSource.The first time the page comes up (!IsPos

Note: This question has been completely modified now that I have a simpler example.

I have set up a sample page which only has a ListView and ObjectDataSource. The first time the page comes up (!IsPostBack), my GetList method is called once. After paging (IsPostBack), the GetList method is called twice--the first time with the old paging values and the second time with the new values.

If I set EnableViewState="true" on the ListView, then the GetList method is only called once. It seems to me that the ListView wants an "initial state", which it either gets from ViewState or by re-running the method.

Is there any way to disable ViewState on the ListView and also prevent SelectMethod from being called twice?

ASPX page:

    <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 code-behind:

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;开发者_StackOverflow set; }
    }
}


Either turn ODS caching on.

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

This way the GetList will be called only when new data is needed. Post backs to pages that already had data retrieved will use the cached version and not call the GetList.

Or move your DataPager out of the ListView and set the PagedControlID property.


Actually you should be using the OnSelecting event.

What happens is that ObjectDataSource calls the method SelectMethod twice

  1. First time it gets the data.
  2. Next time it gets the count.

So I think you have to implement the OnSelecting event

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

and then cancel the event when the ObjectDataSource tries to call the count method.

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

You can look for full implementation as mentioned in the link below http://www.unboxedsolutions.com/sean/archive/2005/12/28/818.aspx

Hope this helps.


I had a similar problem where it worked different depending on browser. IE one way and all other browsers one way.. Might not be the same issue as you have.

I solved it this way:

        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;           
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消