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:
<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>
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;
GrdCountry.BackColor = Color.LightGreen;
GrdCountry.AlternatingRowStyle.BackColor = Color.LightPink;
GrdCountry.RowStyle.BackColor = Color.LightCyan;
GrdCountry.GridLines = GridLines.None;
GrdCountry.CellPadding = 15;
}
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()}");
}
}
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