DataContract attribute effects serialization despite IgnoreSerializableAttribute

May 31, 2012 at 2:22 PM

Hi,

A type deriving from a type decorated with the [DataContract] attribute does not get correctly serialised under Json.net 4.5.6 - I see only {} whereas on version 3.5 it serialised it correctly.

See example below which outputs only {} when run against Json.net 4.5.6, but outputs {"forename":"john","surname":"smith"} when run against v3.5. I've tried using a DefaultContractResolver with IgnoreSerializableAttribute=true but this doesn't resolve the issue. Any ideas?

using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;

namespace ConsoleApplication4
{
	class Program
	{
		static void Main(string[] args)
		{
			var entity = new Entity {forename = "john", surname = "smith"};
			Console.WriteLine(JsonConvert.SerializeObject(entity));

			Console.ReadLine();
		}
	}

	public class Entity : Base
	{
		public virtual string forename { get; set; }
		public virtual string surname { get; set; }
	}

	[DataContract]
	public class Base
	{
	}
}

Thanks,

 

Al

 

Coordinator
May 31, 2012 at 9:22 PM

4.5.6 detects the DataContractAttribute on the base class and assumes opt-in serialization.

Jun 1, 2012 at 8:55 AM

Are there any plans to revert this breaking change or add a flag like the IgnoreSerializableAttribute?

Coordinator
Jun 1, 2012 at 11:24 AM

No

Jun 16, 2012 at 3:44 AM
Edited Jun 17, 2012 at 4:25 AM
Argh!! Im having the exact same problem.

I agree that this needs to be fixed, that the serializer is not behaving correctly.

According to MS documentation
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false,�AllowMultiple = false)]
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute(v=vs.95).aspx

DataContractAttribute should NOT be inherited from base types.The problem appears to be in JsonTypeReflector.GetDataContractAttribute - it forcefully traverses the inheritance hierarchy to root, to locate a DataContractAttribute.

    public static DataContractAttribute GetDataContractAttribute(Type type)
    {
      // DataContractAttribute does not have inheritance
      Type currentType = type;
 
      while (currentType != null)
      {
        DataContractAttribute result = CachedAttributeGetter<DataContractAttribute>.GetAttribute(currentType.GetCustomAttributeProvider());
        if (result != null)
          return result;
 
        currentType = currentType.BaseType();
      }
 
      return null;
    }

I have written a simple resolver that takes care of it for me (and also a problem where Json.net now also uses custom typeconverters where possible, another breaking change for our ptoject).
You can find it here:http://stackoverflow.com/questions/11044639/newtonsoft-json-serializer-returns-empty-object