Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting anonymous type to dynamic

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); } 
like image 471
gdoron is supporting Monica Avatar asked Dec 11 '11 15:12

gdoron is supporting Monica


People also ask

What are difference between anonymous and dynamic types?

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.

Do anonymous types work with Linq?

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.

Can a method return an anonymous type C#?

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.

What is an ExpandoObject?

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.


2 Answers

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.

like image 172
Marc Gravell Avatar answered Sep 24 '22 02:09

Marc Gravell


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;     } } 
like image 25
Hafthor Avatar answered Sep 23 '22 02:09

Hafthor