C# Convert or Cast ExpandoObject to Specific Class Object
Asked Answered
P

2

7

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

Pteridology answered 28/12, 2020 at 10:0 Comment(1)
If there's a server and a client, there's some method of communication between them. You don't solve this problem through ExpandoObject, you solve it through proper serialization and deserializationGimmal
B
25

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://learn.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

Bathesda answered 28/12, 2020 at 10:31 Comment(5)
It Works. But can you tell me why can't I convert it directly? I'm a new c# programer.Pteridology
@PhuminMukem to be honest, I feel hard to explain it in simple way but I update answer with reference about how C# Cast works and hope this helps youCarley
that is very good solutions, you saved me dayWrap
You can use System.Text.Json.JsonSerializer as well, not only Newtonsoft.Json.JsonConvert.Tirrell
Your solution worked among lots of solutions. Thanks. :)Douala
P
4

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.

Pyxis answered 20/2, 2022 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.