I have a function that returns an anonymous type which I want to test in my MVC controller.
public JsonResult Foo() { var data = new { details = "something", more = "More" }; return Json(data); }
I want to verify the data I get from the Foo function, What I'm doing now is getting the data type and get it's properties values with reflection.
[Test] public void TestOne() { var data = _controller.Foo().Data; var details = data.GetType().GetProperty("details").GetValue(data, null); var more = data.GetType().GetProperty("more").GetValue(data, null); Assert.AreEquals("something", details); Assert.AreEquals("More", more); }
Is there a simple way similar to this to check the anonymous properties?
[Test] public void TestTwo() { var data = (dynamic) _controller.Foo().Data; var details = data.details; // RunTimeBinderException object does not contain definition for details var more = data.more; Assert.AreEquals("something", details); Assert.AreEquals("More", more); }
Anonymous type is a class type that contain one or more read only properties whereas dynamic can be any type it may be any type integer, string, object or class. Anonymous types are assigned types by the compiler.
You are allowed to use an anonymous type in LINQ. In LINQ, select clause generates anonymous type so that in a query you can include properties that are not defined in the class.
As in the preceding facts you cannot return an anonymous type from a method, if you do want to return one then you need to cast it to an object.
The ExpandoObject class enables you to add and delete members of its instances at run time and also to set and get values of these members. This class supports dynamic binding, which enables you to use standard syntax like sampleObject. sampleMember instead of more complex syntax like sampleObject.
Anonymous objects are internal
, which means their members are very restricted outside of the assembly that declares them. dynamic
respects accessibility, so pretends not to be able to see those members. If the call-site was in the same assembly, I expect it would work.
Your reflection code respects the member accessibility, but bypasses the type's accessibility - hence it works.
In short: no.
This blog had a working answer: http://blog.jorgef.net/2011/06/converting-any-object-to-dynamic.html - Thanks @Jorge-Fioranelli.
public static class DynamicExtensions { public static dynamic ToDynamic(this object value) { IDictionary<string, object> expando = new ExpandoObject(); foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType())) expando.Add(property.Name, property.GetValue(value)); return expando as ExpandoObject; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With