Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing dynamic model in MVC5 Razor View [duplicate]

I'm trying to pass dynamic results to View from Controller, method ShowColor returns dynamic results. In View I try to loop through the collection but I'm getting error

'object' does not contain a definition for 'ColorID'.

I have the following code in Controller and View

public class myColor
{
    public int ID { get; set; }
    public string  Name { get; set; }
    public string Like { get; set; }
}

public dynamic ShowColor()
{
    IList<myColor> color = new List<myColor>();
    color.Add(new myColor { ID = 1, Name = "Red", Like = "***" });
    color.Add(new myColor { ID = 2, Name = "Green", Like = "*****" });
    color.Add(new myColor { ID = 3, Name = "Blue", Like = "**" });
    color.Add(new myColor { ID = 4, Name = "Yellow", Like = "*" });

    var select = (from c in color
                  select new
                  {                     
                      ColorID = c.ID,
                      ColorName = c.Name
                  }).ToList();

    return select;
}
public ActionResult DBDynamic()
{
    return View(ShowColor());
}

View

@model dynamic

@{
    ViewBag.Title = "DBDynamic";
}

<h2>DBDynamic</h2>

<p>
    <ul>
        @foreach (var m in Model)
        {
            <li> @m.ColorID</li>            
        }
    </ul>

</p>

Error

Debug Image

Found the solution here and a nice blog here:

public static ExpandoObject ToExpando(this object anonymousObject)
{
    IDictionary<string, object> expando = new ExpandoObject();
    foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
    {
        var obj = propertyDescriptor.GetValue(anonymousObject);
        expando.Add(propertyDescriptor.Name, obj);
    }

    return (ExpandoObject)expando;
}

And call it like this

    var select = (from c in color
                select new
                {
                    ColorID = c.ID,
                    ColorName = c.Name
                })
                .AsEnumerable()
                .Select(x => x.ToExpando());

return View(select);
like image 548
sairfan Avatar asked Dec 08 '14 17:12

sairfan


1 Answers

An anonymous object is not the same thing as a dynamic. If you want to use it like a dynamic then cast it to that:

@foreach (dynamic m in Model)

However, dynamics are best avoided if at all possible. You lose all compile-time checking and even intellisense. You won't know if you fat-fingered a property name until runtime or even if you've accidentally used the wrong type of thing the wrong way until runtime. If something is broken, you want to know about it at compile-time, not when it's already live and affecting users, when you may not even know that an error has occurred unless a user notifies you. That's a horrible situation for your app to be in.

Long and short, use strong types. If you want something with properties, ColorID and ColorName, create a view model with those properties and select your query into instances of that type. Then, everything will be nice and strongly-typed and you'll know well in advance if there's some error or problem with your code.

like image 163
Chris Pratt Avatar answered Sep 19 '22 22:09

Chris Pratt