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 th
Okay sorry I just don't agree that this is horrible etc etc. Yes I would never consider doing this stuff on a production site - but for a prototyping, non-commercial, internal-only, for-testing-purposes I think using this approach is perfectly valid.
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
:
ViewBag.SomeData = Enumerable.Range(1,10).Select(i=> {
var toReturn = new ExpandoObject();
toReturn.Value = i;
return toReturn;
});
Which is almost as short as the anonymous type just not as clean.
But then I wondered if I could possibly get away with grabbing the publicly readable members out of the anonymous type (possibly relies on compiler internals - the type is internal, but the properties it generates are public):
public static class SO7429957
{
public static dynamic ToSafeDynamic(this object obj)
{
//would be nice to restrict to anonymous types - but alas no.
IDictionary toReturn = new ExpandoObject();
foreach (var prop in obj.GetType().GetProperties(
BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead))
{
toReturn[prop.Name] = prop.GetValue(obj, null);
}
return toReturn;
}
}
Which means I can then use my original code - but with a little extension method call tagged on the end:
ViewBag.SomeData=Enumerable.Range(1,10).Select(i=> new { Value = i }.ToSafeDynamic());
And do you know what - I know it's not efficient, and most people will say it's ugly; but it'll saved me time and allow me to focus on writing features in my test site for my QA team to use in testing the real thing (whose code is, of course immaculate throughout :) ).