When we serialize a serializable object using JSON.Net, the JSON string is different from the DatacontractJSON serializer

I have a class like below

[Serializable] public class sample { private int m_width; private int m_height; public int Width { get { return this.m_width; } set { this.m_width = value; } } public int Height { get { return this.m_height; } set { this.m_height = value; } } } 

If I use a DataContractJsonSerializer to serialize an object of this class, I get a json string, as shown below:

 {"m_height":1345,"m_width":1234} 

If I use Newtonsoft.Json.dll for serialization, I get the following code:

 {"Width":1234,"Height":1345} 

Why does the DataContractSerializer use fallback fields for serialization if the class is marked as serializable?

Is there a way that I can achieve the same using Newtonsoft.Json.dll

+4
source share
5 answers

We have some objects that are marked as [Serializable] , so they can be serialized using traditional methods, but we must have purely serialized in JSON for use with the Web API. Setting IgnoreSerializableAttribute to true will stop Newtonsoft.Json from behaving like Microsoft serializers, and instead it just serializes the public properties.

TL; DR: add this to WebApiConfig.cs:

 ((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true; 
+2
source

If you do not always communicate with WCF in WCF, the best option is probably to use the Newtonsoft serializer. Unfortunately, the MS serializer seems to comply with some Microsoft standards that do not meet the standards that many web applications expect.

The Newtonsoft serializer seems more standard, and even MS uses it for the WebAPI and in the web API http client (nuget will pull it out for you).

Here's another difference you'll find - try serializing the DateTime type. You will find that the DataContract serial disk serializes the value in a different format that is incompatible with other JSON (you will notice some abbreviations in it). I understand that this alternative format was used by some AJAX WebForm controls, but it is specific to Microsoft Webforms.

Here's a bit more info on dates: http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx

+1
source

Here is another thing you can pay attention to:

The differences between the DataContractJsonSerializer and Newtonsoft are still there, but as for why you get weird serialization behavior, you mix your serialization standards.

The [Serializable] attribute refers to earlier .Net serialization. DataContractSerialization is backward compatible, but the behavior may be different.

If you want to do this with the datacontract method, mark the class with [DataContract] instead, and mark each public member that you want to serialize with the [DataMember] attribute. (or remove all serialization attributes, and it should use all public properties by default)

This should explain the difference that is visible, but I would still recommend that you use the Newtonsoft serializer.

+1
source

The DefaultContractResolver class in Newtonsoft.Json.dll I found some code that sets the IgnoreSerializableAttribute property to true.

 #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) IgnoreSerializableAttribute = true; #endif 

I am using the DotNet4.0 dll, so this property is true and ignores the Serializable attribute. if I make it false it gives the same result as the DataContractSerializer

+1
source

The DataContract serializer requires that you explicitly label the class with the [DataContract] attribute, and then mark each required property that must be serialized using the [DataMember] .

If you do this, you will find that the same json string will exit using another class. The problem you are facing is related to differences in how 2 serializers handle default serialization (without additional information):

  • DataContract serializes all private fields unless otherwise specified

  • NewtonSoft serializes all public properties unless otherwise specified

On how to make Newtonsoft serialize private fields, I have no other idea than to create a wrapper class with the m_Width and m_Height properties, which on setters and recipients put values ​​in the correct target properties of the actual object

0
source

Source: https://habr.com/ru/post/1497800/


All Articles