简体   繁体   中英

Json.NET serialization error

This example code is a simplified version of my project, the _lockObject is legacy and cannot be removed I have the following class

 [DataContract(IsReference = true)]
 public class test 
 {
     [DataMember]
     private static object _lockObject = new object();
     [DataMember]
     private int num;
 }

And I try to serialize it using Json.NET as follows :

StringBuilder sb = new StringBuilder();
TextWriter text = new StringWriter(sb);

var serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.Auto;

serializer.PreserveReferencesHandling = PreserveReferencesHandling.None;
serializer.NullValueHandling = NullValueHandling.Ignore;
serializer.TraceWriter = new MemoryTraceWriter();
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;

serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
serializer.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full;

var test = new test();
serializer.Serialize(text, test);

I get an error

Error getting value from '_lockObject'

If i remove the static from _lockObject the serialization is successful

The problem is that _lockObject is static field. Static fields are not serializable by default. And IMO you shouldn't serialize it.

Allowing a lock object to be deserialized into is a bad idea because it allows the locking mechanism to be defeated. If you're just looking for a way to satisfy legacy serialization requirements without screwing up your locking mechanism, I propose that you introduce a dummy non-static member to stand in for the lock object on serialization and deserialization. Define your class like this instead:

[DataContract(IsReference = true)]
public class test 
{
    // DO NOT include this in serialization
    private static object _lockObject = new object();

    // This dummy object stands in for _lockObject for purposes of serialization
    // but is not referenced elsewhere in the code
    [DataMember(Name = "_lockObject")]
    private object dummy = new object();

    [DataMember]
    private int num;
}

The code can continue to reference the static _lockObject , while the external world sees the value of the dummy object instead, and is none the wiser. Now the value of _lockObject cannot be inadvertently changed through deserialization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM