Reputation: 10478
Edit: Seems numerous people think this is a dumb idea, so I would appreciate an explanation of why it's bad? I was trying to make one partial view that could handle a list of any models to display in table format. I was planning on extending it then to allow also take config options to say what columns to display and add extra ones after I figured out the basics. Is there a better way to do this?
How does one use a list of expando objects in views? I am trying to make a view that can display a table format of a list of any of my models, and it looks like expando object is a good fit for this, but I can't figure out how to get the iterations properly.
I tried using these links: Dynamic Anonymous type in Razor causes RuntimeBinderException, ExpandoObject, anonymous types and Razor but they seem either incomplete or not what what I am doing.
Here is my view:
@using System.Reflection
@model IList<dynamic>
<h2>ExpandoTest</h2>
@if(Model.Count > 0)
{
<table>
@foreach (dynamic item in Model)
{
foreach(var props in typeof(item).GetProperties(BindingFlags.Public | BindingFlags.Static))
{
<tr>
<td>
@props.Name : @props.GetValue(item, null)
</td>
</tr>
}
}
</table>
}
My controller:
public ActionResult ExpandoTest()
{
IList<dynamic> list =
EntityServiceFactory.GetService<UserService>().GetList(null, x => x.LastName).ToExpando().ToList();
return View(list);
}
Extension method:
public static IEnumerable<dynamic> ToExpando(this IEnumerable<object> anonymousObject)
{
IList<dynamic> list = new List<dynamic>();
foreach(var item in anonymousObject)
{
IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(item);
IDictionary<string, object> expando = new ExpandoObject();
foreach (var nestedItem in anonymousDictionary)
expando.Add(nestedItem);
list.Add(expando);
}
return list.AsEnumerable();
}
The list of expando items are being properly created I can see through debugging, but in the view it says item can not be resolved in the typeof(item)
statement and throws the error saying type item cannot be found. If I try item.GetType().GetProperties()
that returns nothing. Now I understand that these don't work because the type is dynamic, but how can I dynamically display the properties and values then?
Upvotes: 3
Views: 4018
Reputation: 1613
You can cast a ExpandoObject to an IDictionary, and do something like this:
foreach(var prop in item as IDictionary<string, object>)
{
<tr>
<td>
@prop.Key
@prop.Value
</td>
</tr>
}
Upvotes: 3