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
Dec 26, 2014 at 10:14 AM
Is there a bug filed for this? It goes against the intention of the attribute not to be inherited and has caused hours of wasted time when working with Web API and data access libraries that use a base class with the attribute.

[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
public sealed class DataContractAttribute : Attribute

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute(v=vs.110).aspx