0
votes

I have some trouble about deserializing a message into an undefined object. I call this an undefined object because I don't have any proper class that resemble the data of the message. I only have an interface. Since the project I'm onto is kinda heavy, I won't display every single line of code except if you feel the need to ask.

I have an interface let's call it ITest (That itself implements other interfaces and other class. So it's quite a complex one)

And in my scope, I receive a "message" Serialized with JsonConvert following exactly the pattern of this Interface ITest. I won't go into details how it was actually serialize, but the solution cannot be used for the deserialize aspect. And here comes the problem :

Since I have to deserialize this message into an interface, well... I obviously can't. So I tried many (MANY) workaround that. Using other Nuget (Like "Impromptu Interfaces" or Castle.Core), or even AutoMapping my interface to an Object type (dynamic), but either the code won't compile, or I get only half of the data or I get only the properties with null/0 values. The closest I got to was with Impromptu... I'm kinda desperate right now.

I would like not to make those damn Concrete type. Since I would need a lot of them. DRY concept is bleeding rn :(

Here is Impromptu

var obj = ActLike<ITest>(message)

Here is AutoMapping

    public interface ITest
    {
        string Test { get; set; }
        int Val { get; set; }
    }

    static void Main(string[] args)
    {
        Mapper.Initialize(cfg => { });

        var a = new { Test = "test", Val = 1 };
        ITest b = Mapper.Map(a, typeof(Object), typeof(ITest)) as ITest;

    }

Where I tried to change that damn "var a" into a dynamic Json object to be used into the mapping. And many other things ...

So yeah ... I'm kinda stuck right now.

Thanks for any help you could give me !

2
Are you able to modify the serialize portion? - Ryan Schlueter
@dbc Well I didn't think about Moq ... I'll try it out as soon as I can. - Benjamin MASSET
@RyanSchlueter I kinda can. Not as much as I want. - Benjamin MASSET

2 Answers

0
votes

I may be missing part of the problem but this may be an option. Adding a little type information to your serialized object.

  static void Main(string[] args)
    {
        var objectToSerialize = new List<IFoo>() {
            new TestClass()
            {
                Test = "A",
                Test2 = "B"
            },
              new TestClass2()
            {
                Test = "C",
                Test3 = "D"
            },

        };
        // TODO: Add objects to list
        var jsonString = JsonConvert.SerializeObject(objectToSerialize, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
        var deserializedObject = JsonConvert.DeserializeObject<List<IFoo>>(jsonString, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
        var result = deserializedObject;
    }
}

internal interface IFoo
{
     string Test { get; set; }
}
public class TestClass : IFoo
{
    public string Test { get; set; }
    public string Test2 { get; set; }
}
public class TestClass2 : IFoo
{
    public string Test { get; set; }
    public string Test3 { get; set; }
}
0
votes

I kinda found a solution using MassTransit proxy system going along those lines :

            JsonSerializer jsonMessageDeserializer = JsonMessageSerializer.Deserializer;

            Type type = typeof(T);
            if (type.IsInterface && TypeMetadataCache.IsValidMessageType(type))
                type = TypeMetadataCache.GetImplementationType(type);

            using (Stream body = new MemoryStream(Encoding.UTF8.GetBytes(message)))
                using (StreamReader streamReader = new StreamReader(body, Encoding.UTF8, false, 1024, true))
                    using (JsonTextReader jsonTextReader = new JsonTextReader((TextReader)streamReader)) 
                    {
                        Object objBody = jsonMessageDeserializer.Deserialize((JsonReader)jsonTextReader);
                        JsonReader r = ((JsonReader)new JTokenReader(GetMessageToken((objBody))));
                        object obj2 = jsonMessageDeserializer.Deserialize(r, type);