I have an MVC3 site that I’ve setup for testing another site – most of it has been quick and dirty, and so I’ve not gone to town creating model and view model types for all the views – only where input is requried from the user.
Okay so I have a controller method that projects a Linq sequence and sets it into ViewBag.
ViewBag.SomeData = Enumerable.Range(1,10).Select(i=> new { Value = i });
In my view (Razor C#) I then want to read this – quite simple:
@foreach(dynamic item in ViewBag.SomeData)
{
@:Number: @item.i
}
Except, of course, I get a RuntimeBinderException because the anonymous type created in the controller is internal to the web project’s output assembly and the actual Razor code here will be running in a different assembly generated by the build manager so, all in all DENIED!
Obviously a ‘proper’ model type would solve the issue – but let’s say I simply don’t want to do that because that’s my prerogative(!) – how best to keep the code to a minimum and retain the dynamic-ness here?
This is what I’ve done (and I stress this only really addresses the issue adequately for anonymous types); lifting the members out and pushing them into an
ExpandoObject.My initial change was to make the projection a multi-statement that returns an
ExpandoObject:Which is almost as short as the anonymous type just not as clean.
But then I wondered if I could grab the publicly readable members out of the anonymous type (the type is internal, but the properties it generates are public):
Which means I can then use my original code – but with a little extension method call tagged on the end:
It’s not efficient, and it should definitely not be used for serious production code. But it’s a good time saver.