Click here to Skip to main content
15,352,563 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi All,

recently I started a discussion about loading data in GridView component. Richard Deeming pointed me out to the SelectMethod option in asp.net 4.5 and newer.
I created a test website that call my OData service using LINQ in the SelectMethod.
When I set AllowPaging to false I see a long list of users appear in my website. Setting it to true leads to a must be reducible node error.
If the setting is changed in asp this happen but also if I set the value to true in the Page_LoadComplete method.

The error occurs in a Validation part in asp.net of which I have no control.

Has anyone had this same problem? And how did you solve it?
Richard Deeming and I suspect the OData web api service despite the call is done with $orderby=....

What I have tried:

ASP.NET
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView runat="server" ID="GrdTest"
                AutoGenerateColumns="false" DataKeyNames="Id" 
                ItemType="Global.MarinGlobalService.Models.User"
                SelectMethod="GrdTest_GetData"
                AllowSorting="true"
                AllowPaging="false" PageSize="10"
                OnRowDataBound="GrdTest_RowDataBound"
                >
                <Columns>
                    <asp:DynamicField DataField="Id" HeaderText="Id" SortExpression="Id" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Right"/>
                    <asp:DynamicField DataField="Name" HeaderText="Name" SortExpression="Name" HeaderStyle-HorizontalAlign="Left" />
                    <asp:DynamicField DataField="SurName" HeaderText="Surname" SortExpression="Surname" HeaderStyle-HorizontalAlign="Left" />
                    <asp:DynamicField DataField="GivenName" HeaderText="GivenName" HeaderStyle-HorizontalAlign="Left" />
                    <asp:TemplateField HeaderText="In #Usergroups" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Right">
                        <HeaderTemplate><asp:Label runat="server" ID="GrdCount" /></HeaderTemplate>
                        <ItemTemplate><%# Item.UserGroup?.Count %></ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
        <div>
            <asp:GridView runat="server" ID="GrdCountry"
                AutoGenerateColumns="true" DataKeyNames="Id" 
                ItemType="Global.MarinGlobalService.Models.Country"
                SelectMethod="GrdCountry_GetData"
                AllowSorting="true"
                AllowPaging="false" PageSize="10"
                OnRowDataBound="GrdCountry_RowDataBound"
                >

            </asp:GridView>
        </div>
    </form>
</body>

C#
public partial class Index : Page
    {

        private Container container;
        private IQueryable<User> users;
        private IQueryable<Country> countries;
        protected void Page_Init(object sender, EventArgs e)
        {
            Uri uri = new Uri("http://localhost/api/global");
            container = new Container(uri)
            {
                Credentials = CredentialCache.DefaultNetworkCredentials,
                Timeout = 3600
            };

        }
        protected void Page_LoadComplete(object sender, EventArgs e)
        {
            GrdTest.BackColor = Color.LightGreen;
            GrdTest.AlternatingRowStyle.BackColor = Color.LightPink;
            GrdTest.RowStyle.BackColor = Color.LightCyan;
            GrdTest.GridLines = GridLines.None;
            GrdTest.CellPadding = 15;
            //GrdTest.AllowPaging = true;

            GrdCountry.BackColor = Color.LightGreen;
            GrdCountry.AlternatingRowStyle.BackColor = Color.LightPink;
            GrdCountry.RowStyle.BackColor = Color.LightCyan;
            GrdCountry.GridLines = GridLines.None;
            GrdCountry.CellPadding = 15;
        }

        // The return type can be changed to IEnumerable, however to support
        // paging and sorting, the following parameters must be added:
        //     int maximumRows
        //     int startRowIndex
        //     out int totalRowCount
        //     string sortByExpression
        public IQueryable<User> GrdTest_GetData(int? maximumRows, int? startRowIndex, out int? totalRowCount, string sortByExpression)
        {
            users = container.Users.OrderBy(x => x.Id);

            totalRowCount = users.Count();
            if (!string.IsNullOrWhiteSpace(sortByExpression))
            {
                string[] expressions = sortByExpression.ToLower().Split(' ');
                bool descend = (expressions.Length == 2);

                switch (expressions[0])
                {
                    case "id":
                        if (descend)
                            users = container.Users.OrderByDescending(x => x.Id);
                        else users = users.OrderBy(x => x.Id);
                        break;
                    case "name":
                        if (descend)
                            users = container.Users.OrderByDescending(x => x.Name);
                        else users = users.OrderBy(x => x.Name);
                        break;
                    case "surname":
                        if (descend)
                            users = container.Users.OrderByDescending(x => x.Surname);
                        else users = container.Users.OrderBy(x => x.Surname);
                        break;
                    case "givenname":
                        if (descend)
                            users = container.Users.OrderByDescending(x => x.GivenName);
                        else users = container.Users.OrderBy(x => x.GivenName);
                        break;
                }
            }
            if (maximumRows != null)
                return users.Skip(startRowIndex ?? 0).Take(maximumRows ?? 0); // 
            return users;

        }

        protected void GrdTest_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                if (e.Row.FindControl("GrdCount") is Label lbl)
                    lbl.Text = Server.HtmlDecode($"#Users:<br /> {users.Count()}");
            }
        }

        protected void GrdCountry_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                if (e.Row.FindControl("GrdCount") is Label lbl)
                    lbl.Text = Server.HtmlDecode($"#Countries:<br /> {countries.Count()}");
            }
        }

        // The return type can be changed to IEnumerable, however to support
        // paging and sorting, the following parameters must be added:
        //     int maximumRows
        //     int startRowIndex
        //     out int totalRowCount
        //     string sortByExpression
        public IQueryable<Country> GrdCountry_GetData(int? maximumRows, int? startRowIndex, out int? totalRowCount, string sortByExpression)
        {
            countries = container.Countries.OrderBy(x => x.Name);
            totalRowCount = countries.Count();
            return countries.AsQueryable(); 
        }
    }

[ArgumentException: must be reducible node]
   System.Linq.Expressions.Expression.VisitChildren(ExpressionVisitor visitor) +97
   System.Linq.Expressions.ExpressionVisitor.VisitExtension(Expression node) +11
   System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor) +12
   System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) +20
   System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes) +60
   System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node) +43
   System.Web.Util.OrderingMethodFinder.VisitMethodCall(MethodCallExpression node) +43
   System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor) +12
   System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) +20
   System.Web.Util.OrderingMethodFinder.OrderMethodExists(Expression expression) +38
   System.Web.UI.WebControls.QueryableHelpers.IsOrderingMethodFound(IQueryable`1 queryable) +16
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900