question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JsonConvert is altering original object

See original GitHub issue

Source/destination types

// Put the types you are serializing or deserializing here
// Including only the interesting part

[DataContract]
public class ConnectedAccountIdentity
{
    [DataMember]
    public string AuthenticationType { get; set; }
   
    [DataMember]
    public bool IsAuthenticated { get; set; }

    [DataMember]
    public List<ConnectedAccountClaim> Claims { get; set; } = new List<ConnectedAccountClaim>();
}

public class ConnectedAccountClaim
{
    public string Type { get; set; }
    public string Value { get; set; }
    public string ValueType { get; set; }
    public string Issuer { get; set; }
    public string OriginalIssuer { get; set; }
}

[DataContract]
public class ConnectedAccount
{
    [DataMember]
    public ConnectedAccountIdentity Identity { get; set; }

    [DataMember]
    public IPAddress IPAddress { get; set; }
}
// Really big, only part related to the previous C#

{  
   "ConnectedAccount":{  
      "Identity":{  
         "AuthenticationType":"BearerIdentityServerAuthenticationIntrospection",
         "IsAuthenticated":true,
         "Claims":[  
            {  
               "Type":"iss",
               "Value":"http://auth-central.i-2a.me:8443",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"nbf",
               "Value":"1538148765",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"exp",
               "Value":"1538150565",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"aud",
               "Value":"http://auth-central.i-2a.me:8234/resources",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"aud",
               "Value":"api",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"client_id",
               "Value":"I2AWeb",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"sub",
               "Value":"toto@domain.com",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"auth_time",
               "Value":"1537273522",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"idp",
               "Value":"i2a_central",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"amr",
               "Value":"external",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"name",
               "Value":"toto@domain.com",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"role",
               "Value":"support",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"isFullSupport",
               "Value":"True",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"federationId",
               "Value":"256ab23a-a40a-4cf8-82c9-84e534cedc20",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"active",
               "Value":"True",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            },
            {  
               "Type":"scope",
               "Value":"api",
               "ValueType":"http://www.w3.org/2001/XMLSchema#string",
               "Issuer":"LOCAL AUTHORITY",
               "OriginalIssuer":"LOCAL AUTHORITY"
            }
         ]
      },
      "IPAddress":"127.0.0.1"
   },
   "CorrelationId":"f5318d6f-e5e2-4178-bc96-325f76f4a23c"
}

Expected behavior

We serialize an object to a string. A few lines / method calls later, we deserialize the content.

I don’t even how it is possible, but deserializing the object alters the original. You can see in the video, the values of the original object is changing while we deserialize the string.

We added the code in a try / catch to explicit the issue.

Actual behavior

The original values should not be altered. The results of the deserialization should be different.

Steps to reproduce


        protected override TenantMessage BuildMessage(string eventType, object value, bool onlyOnce)
        {
            var msg = base.BuildMessage(eventType, value, onlyOnce);

            var tenant = Singleton<EnvironmentContextManager>.GetInstance().GetTenant();
            msg.TenantId = tenant?.Id;

            try
            {

                var serialization = Newtonsoft.Json.JsonConvert.SerializeObject(value);

                var model1 = Newtonsoft.Json.JsonConvert.DeserializeObject<AlertEventArgs>(serialization);
                var model2 = Newtonsoft.Json.JsonConvert.DeserializeObject<AlertEventArgs>(serialization);

            }
            catch { }



            return msg;
        }

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
frankelycommented, Nov 7, 2018

Is this a valid issue? Does this still need to be open?

1reaction
ldubroiscommented, Oct 1, 2018

Here a better link (with no expiration) : Video

It seems we found out the origin, but I don’t understand why it works like this. The models described below are part of a bigger object. In one constructor of this bigger object, we set the ConnectedAccount to some kind of thread local / static field.

During the deserialization, instead of recreating the object, it uses what the constructor does.

A simplier exemple would be :


         static List<string> VALUES = new List<string>();

        public class MyObj
        {
            public string Property2 { get; set; }

            public bool Property1 { get; set; }

            public List<string> Values { get; set; } = VALUES;
        }

        static void Main(string[] args)
        {

            var v1 = new MyObj();
            v1.Values.Add("Value1");

            var serialized = JsonConvert.SerializeObject(v1);

            var v2 = JsonConvert.DeserializeObject<MyObj>(serialized);
            var v3 = JsonConvert.DeserializeObject<MyObj>(serialized);


            Console.ReadLine();
        }

v1, v2 and v3 shares the same Values collection. At the end, the Values collection contains 3 elements (3 times "Value1").

Read more comments on GitHub >

github_iconTop Results From Across the Web

JsonConvert.SerializeObject is changing a property value ...
JsonConvert.SerializeObject is changing a property value from letters to a number. I say 'letters' and 'number' as its a dynamic source object, ...
Read more >
Preserving Object References
The PreserveReferencesHandling setting on the JsonSerializer will change how all objects are serialized and deserialized. For fine grain control over which ...
Read more >
JSON.stringify() - JavaScript - MDN Web Docs
A function that alters the behavior of the stringification process, or an array of strings and numbers that specifies properties of value to...
Read more >
Migrate from Newtonsoft.Json to System.Text.Json - .NET
The System.Text.Json namespace provides functionality for serializing to and deserializing from JavaScript Object Notation (JSON). The System.
Read more >
How to write custom converters for JSON serialization - .NET
Json , see How to serialize and deserialize JSON in .NET. A converter is a class that converts an object or a value...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found