I am trying to build an expression tree dynamically for sorting. The sorting will happen at the action filter of my web api. So the type of object will be unknown until runtime.
Here's the overview:
At the action filter level:
IEnumerable<object> model = null;
context.Response.TryGetContentValue(out model);
model=model.OrderByExtension(orderByField, orderDirection);
context.Response.Content=new ObjectContent<IEnumerable<object>>(model, new JsonMediaTypeFormatter());
And the extension method:
public static IQueryable<T> OrderByExtension<T>(this IQueryable<T> source, string sortProperty, Sorting.SortingOption sortOrder)
{
var type = source.FirstOrDefault().GetType(); //Gets the type of object passed, since typeof(T) is only object at this point
var property = type.GetProperty(sortProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var typeArguments = new Type[] { typeof(T), property.PropertyType };
var methodName = sortOrder == Sorting.SortingOption.Asc ? "OrderBy" : "OrderByDescending";
var resultExp = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
On the Expression.Call - I get the error: No generic method 'OrderByDescending' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments.
I am assuming there is a mismatch between the type 'object' and the actual type when the OrderBy method is invoked.
Is there anyway to get this to work ?
Thanks in advance. ps: I also tried to create a generic method for OrderBy via .MakeGenericMethod - but no success.