The reason of RuntimeBinderException triggered, I think there have good answer in other posts. I just focus to explain how I actually make it work.
By refer to answer @DotNetWise and Binding views with Anonymous type collection in ASP.NET MVC,
Firstly, Create a static class for extension
public static class impFunctions
{
//converting the anonymous object into an ExpandoObject
public static ExpandoObject ToExpando(this object anonymousObject)
{
//IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject);
IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
IDictionary<string, object> expando = new ExpandoObject();
foreach (var item in anonymousDictionary)
expando.Add(item);
return (ExpandoObject)expando;
}
}
In controller
public ActionResult VisitCount()
{
dynamic Visitor = db.Visitors
.GroupBy(p => p.NRIC)
.Select(g => new { nric = g.Key, count = g.Count()})
.OrderByDescending(g => g.count)
.AsEnumerable() //important to convert to Enumerable
.Select(c => c.ToExpando()); //convert to ExpandoObject
return View(Visitor);
}
In View, @model IEnumerable (dynamic, not a model class), this is very important as we are going to bind the anonymous type object.
@model IEnumerable<dynamic>
@*@foreach (dynamic item in Model)*@
@foreach (var item in Model)
{
<div>[email protected], [email protected]</div>
}
The type in foreach, I have no error either using var or dynamic.
By the way, create a new ViewModel that is matching the new fields also can be the way to pass the result to the view.