C# Convert ot Cast ExpandoObject to Specific Class Object

Viewed 5639

I have a problem to cast or convert ExpandoObject to Object that is specific class in C# project.

Class of Object:

public class PlayerData {
   public string Id {get; set;}
   public string Phone { get; set; }
   public Money Money { get; set; }
}

public class Money {
   public int Cash { get; set; }
   public int Bank { get; set; }
}

When in server sent some data (of type PlayerData) to client side, client see that data in class ExpandoObject. I can use this data as well (like Data.Id, Data.Phone etc.).

In my problem, I need to cast or convert ExpandoObject that I got (It have type PlayerData before) to PlayerData in client side.

Line that cast type :

PlayerData MyData = (PlayerData)Data;

And it return error :

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.

How can I fixed it and cast or convert it correctly?

Note // When I print "Data.GetType()" it return "System.Dynamic.ExpandoObject"

2 Answers

You cannot simply cast type like this. The best way to approach it is using Newtonsoft.Json library with SerializeObject to convert data into string and DeserializeObject to convert string into your type

Try this

PlayerData player = JsonConvert.DeserializeObject<PlayerData>( JsonConvert.SerializeObject(item));

Update: for your question in comment about why you cannot cast object like this

You should refer https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions to understand how C# Cast works

In short, If you write

PlayerData MyData = (PlayerData)Data;

It only works If PlayerData is sub class of Data.GetType() and here is System.Dynamic.ExpandoObject. But it is not true, so you cannot do this

You can also use AutoMapper.

public class Foo {
    public int Bar { get; set; }
    public int Baz { get; set; }
    public Foo InnerFoo { get; set; }
}
dynamic foo = new MyDynamicObject();
foo.Bar = 5;
foo.Baz = 6;

var configuration = new MapperConfiguration(cfg => {});
var mapper = config.CreateMapper();

var result = mapper.Map<Foo>(foo);
result.Bar.ShouldEqual(5);
result.Baz.ShouldEqual(6);

dynamic foo2 = mapper.Map<MyDynamicObject>(result);
foo2.Bar.ShouldEqual(5);
foo2.Baz.ShouldEqual(6);

See details here.

Related