Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialization and deserialization with TypeNameHandling.All looses information about Guid type #762

Closed
centur opened this issue Dec 23, 2015 · 3 comments

Comments

@centur
Copy link

centur commented Dec 23, 2015

Hi,
there might be a bug in SerializeObject when settings have jsonSerializerSettings.TypeNameHandling = TypeNameHandling.All

Here is the small LinqPad repro of this issue
JsonNetBug.zip

The output of the attached code is the following:

======Original Dictionary :
I'm Guid - System.Guid
======Deserialized Dictionary :
I'm Guid - System.String

Although Json.NET can successfully serialize and deserialize Guid when it's an object property, it looses type (struct in this case) information when it's in a collection.

@gabikliot
Copy link

Am I to understand that this is "by design" according to #728 (comment)?

I tried to write a converter for Guid, but it did not work.
Could you please provide more/exact details of how this can be fixed?

I wrote:

public class GuidConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Guid));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Guid guid = (Guid)value;
        writer.WriteStartObject();
        writer.WritePropertyName("Guid");
        writer.WriteValue(value.ToString());
        writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        Guid guid = Guid.Parse(jo["Guid"].ToObject<string>());
        return guid;
    }
}

SerializerSettings = new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.All,
            PreserveReferencesHandling = PreserveReferencesHandling.All,
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DefaultValueHandling = DefaultValueHandling.Ignore,
            MissingMemberHandling = MissingMemberHandling.Ignore,
            NullValueHandling = NullValueHandling.Ignore,
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
        };

SerializerSettings.Converters.Add(new GuidConverter ());
JsonConvert.DeserializeObject(jsonString, SerializerSettings);

But it did not work.

@centur
Copy link
Author

centur commented Jan 5, 2016

Is there any chance that this issue can be addressed and fixed or @JamesNK can take a look on the code above with custom converters and explain why it didn't work

@JamesNK
Copy link
Owner

JamesNK commented Feb 7, 2016

It's by design. Include type information for every primitive value would create a mess.

I'm guessing the converter didn't work because when there is no type data then objectType will be System.Object and this won't pass:

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Guid));
    }

@JamesNK JamesNK closed this as completed Feb 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants