I am trying to write a general view in ASP.NET Core 2.0 that I can use with several Model
Model:
public class MyList<T> : List<T> where T : class
{
public IEnumerable<Expression<Func<T, object>>> Fields { get; set; }
internal MyList(List<T> list, Expression<Func<T, object[]>> fields)
{
var res = new List<Expression<Func<T, object>>>();
var param = Expression.Parameter(typeof(T), "x");
foreach (MemberExpression item in ((NewArrayExpression)fields.Body).Expressions)
{
Expression con = Expression.Property(param, item.Member.Name);
res.Add(Expression.Lambda<Func<T, object>>(con, param));
}
this.Fields = res;
}
}
Creator Model: MyList Class
public static async Task<MyList<T>> CreateAsync<T>(IQueryable<T> qry, Expression<Func<T, Object[]>> Props) where T : class
{
return new MyList<T>(await qry.ToListAsync(), Props);
}
in the controller
var model = await MyList.CreateAsync(qry, x => new[] { x.Name, x.Code});
View:
@model MyList<Color>
<table class="table table-bordered">
<tbody>
@foreach (var item in Model)
{
<tr>
@foreach (var field in Model.Fields)
{
<td>
@Html.DisplayForMe(modelItem => item,field)
</td>
}
</tr>
}
</tbody>
</table>
DisplayForMe Extension
public static IHtmlContent DisplayForMe<TModel, TResult,TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression, Expression<Func<TResult,TValue>> exp2) where TModel : class
{
var con = Expression.Property(expression.Body, ((MemberExpression)exp2.Body).Member.Name);
var oo = Expression.Lambda<Func<TModel, TValue>>(con, expression.Parameters);
return html.DisplayFor(oo);
}
Everything works fine when the T.Name and T.Code Type properties are String. When I go through x.Id (long) proplems is started.
All I want is a way to pass the html.DisplayFor () properties, so I can use the same view to display multiple models (in case I pass the displayed property names from the controller)
I am not familiar with lambda expressions
I tried passing properties as string [], but I don't know how to write a lambda expression that takes a property name and returns the correct expression for
html.DisplayFor<TModel,TResult>(oo)
Please, help!