6

I am using Newtonsoft JSON.NET to serialize/deserialize stuff for me. But I have this list wherein they are of Object type:

var list = new List<Object>() 
{ 
    "hi there", 
    1,
    2.33  
};

When I serialize that with TypeNameHandling set to TypeNameHandling.All, I was expecting that it will also give a $type for each instance on the list but doesn't seem to be the case. Here is the actual output:

{
    "$type": "System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib",
    "$values": [
        "hi there",
        1,
        2.33
    ]
}

I need this to have specific Type Name Handling for those primitive types because if I add an Int32 value in to the list and when it comes back after deserializing it JSON.NET sets it as Int64. That is a big deal for me because I am trying to invoke some methods and to do that I need to compare the parameters and they MUST have the same types. Is there a way or a setting you can set in JSON.NET to achieve what I need?

I've seen this post but what it does is that he is trying to change the default behavior and always return Int32 which is not what I'm looking for.

Any help would be appreciated. Thanks

Community
  • 1
  • 1
Bairose
  • 713
  • 1
  • 7
  • 15
  • You'll need to wrap your primitives inside something like `TypeWrapper` from [Deserialize specific enum into system.enum in Json.Net](https://stackoverflow.com/questions/31351262/deserialize-specific-enum-into-system-enum-in-json-net). – dbc Feb 24 '16 at 03:41

1 Answers1

1

You can create a wrapper class for primitive types, included implicit operators as you want:

class TypeWrapper
{
    public object Value { get; set; }
    public string Type { get; set; }

    public static implicit operator TypeWrapper(long value)
    {
        return new TypeWrapper { Value = value, Type = typeof(long).FullName };
    }

    public static implicit operator long(TypeWrapper value)
    {
        return (long)value.Value;
    }

    public static implicit operator TypeWrapper(int value)
    {
        return new TypeWrapper { Value = value, Type = typeof(int).FullName };
    }

    public static implicit operator int(TypeWrapper value)
    {
        return (int)value.Value;
    }
}

Then you will have element' types when serialize data:

var data = new List<TypeWrapper> { 1, 2L };
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Console.WriteLine(json);

// result: [{"Value":1,"Type":"System.Int32"},{"Value":2,"Type":"System.Int64"}]
tdat00
  • 810
  • 1
  • 8
  • 11
  • 1
    I'm still hoping for a more direct way of doing it (i.e a simple setting change or something). But if there isn't any then this would probably what I will go for. Thanks – Bairose Feb 24 '16 at 10:40
  • 1
    Working solution based on TypeWrapper: https://dotnetfiddle.net/Y0EQKP – user2126375 Oct 20 '20 at 21:36