Shravan Joopally
Shravan Joopally

Reputation: 73

when we serialize serializable object using JSON.Net, JSON string is different from DatacontractJSON serializer

I have a class some thing 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 DataContractJsonSerializer to serialize the object of this class i get the json string as below:

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

If I use Newtonsoft.Json.dll to serialize this I am getting the out put like below:

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

Why DataContractSerializer using backing fields for serialization if class marked as serializable ?

Is there any way I can achieve the same thing using Newtonsoft.Json.dll

Upvotes: 4

Views: 1186

Answers (5)

Richard
Richard

Reputation: 4840

We have some objects which are marked as [Serializable] so they can be serialised using traditional methods, but which we need to have cleanly serialised in JSON for use with Web API. Setting IgnoreSerializableAttribute to true will stop Newtonsoft.Json from behaving like Microsoft's serialisers and instead it will just serialise the public properties.

TLDR: Add this to WebApiConfig.cs:

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

Upvotes: 2

Shravan Joopally
Shravan Joopally

Reputation: 73

DefaultContractResolver class in Newtonsoft.Json.dll i found some code which is setting IgnoreSerializableAttribute property to true.

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

I am using the DotNet4.0 dll so this property set to true and it is ignoring the Serializable attribute. if i make it false it is giving the same output as DataContractSerializer

Upvotes: 1

Adrian Zanescu
Adrian Zanescu

Reputation: 8008

DataContract serializer requires you to explicitly mark the class with the [DataContract] attribute and then mark each desired property to be serialized with the [DataMember] attribute.

If you do that you will find that the same json string will get out as using the other class. The issue you are encountering is due to differences of how the 2 serializers treat the default serialization (without additional information specified):

  1. DataContract serializes all private fields unless otherwise specified

  2. NewtonSoft serializes all public properties unless otherwise specified

On how you can make Newtonsoft serialize the private fields i have no other idea than making a wrapper class with m_Width and m_Height properties that on the setters and geters put the values in the correct target properties of the actual object

Upvotes: 0

JMarsch
JMarsch

Reputation: 21751

Here's another thing you might look at:

The differences between DataContractJsonSerializer and Newtonsoft still stand, but as for why you are getting the weird serialization behavior -- you are mixing your serialization standards.

The [Serializable] attribute pertains to the older .Net serialization. DataContractSerialization is backward compatible, but the behavior might be different.

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

That should explain the difference that are seeing, but I would still recommend that you prefer the Newtonsoft serializer.

Upvotes: 1

JMarsch
JMarsch

Reputation: 21751

Unless you are always communicating from WCF to WCF, your best bet is probably going to be to use the Newtonsoft serializer. Unfortunately, the MS serializer seems to follow some Microsoft-specific standards that do not match the standards that many web apps expect.

Newtonsoft's serializer seems to be more standard, and even MS uses it for WebAPI, and in the Web API http client (nuget will pull it down for you).

Here's another difference that you will find -- try serializing a DateTime type. You will find that the DataContract serialzer serializes the value in a different format that is not compatible with other JSON (you will notice some slashes in it). My understanding is that that alternate format was used by some of the AJAX WebForm controls, but it's specific to Microsoft Webforms.

Here's a little more info about the dates: http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx

Upvotes: 1

Related Questions