3

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?

Community
  • 1
  • 1
SventoryMang
  • 10,275
  • 15
  • 70
  • 113
  • 3
    I'm not trying to be a jerk, but why would this design be a good idea? Like what are the benefits of this? – Joe Feb 10 '12 at 15:52
  • @JoeTuskan Well a common thing to do is display your list of items in a table format, so why not create a partial view that can take any type of items and display it? I just started with a super basic example here since I've never worked with dynamics or expando objects before. Once the basic is down I also plan to hook in some config options to the view so you can control what is displayed, or add additional things. Seems better than creating one for each class individually. Is this a terrible way to go about doing something lik e that? – SventoryMang Feb 10 '12 at 16:06
  • @Joe Tuskan It seems numerous people also agree =(. – SventoryMang Feb 10 '12 at 16:27

1 Answers1

3

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>
}
Felipe Castro
  • 1,623
  • 11
  • 10
  • 1
    Thanks, though I would still like to hear why a lot of people think this is a bad idea. – SventoryMang Feb 10 '12 at 18:08
  • I don't see creating generic controls as something inherently bad. I guess that depends on what you're trying to achieve with that, specially if it is something existent like a [Datagrid](http://stackoverflow.com/questions/159025/jquery-grid-recommendations); in that case, you might be reinventing the wheel. – Felipe Castro Feb 10 '12 at 18:18
  • I see, I wasn't aware of so many options. I can look into these. – SventoryMang Feb 10 '12 at 19:35