Newtonsoft.Json icon indicating copy to clipboard operation
Newtonsoft.Json copied to clipboard

Property that ends with 'Specified' causes non serialisation of similarly named Property

Open nadsmoo opened this issue 4 years ago • 1 comments

When you have 2 properties, one ending with Specified, it causes the other one to not be serialised.

Full working example here: https://dotnetfiddle.net/kswRHW

Thanks for your hard work.

Source/destination types

DateTime?

public class WithSimilarNamedProperties
{
	[JsonProperty(DealCustomFieldsDictionaryStrings.StringOne)] <--- this one will not be serialised at all
	public DateTime? Blurb{	get;	set;	}

	[JsonProperty(DealCustomFieldsDictionaryStrings.StringTwo)]
	public bool BlurbSpecified{get;	set;	}
}

Expected behavior

Should serialise it according to the defined property name.

Actual behavior

The non 'specified' property is not serialised.

Steps to reproduce

Please run the code, or go to https://dotnetfiddle.net/kswRHW

using System;
using Newtonsoft.Json;

public static class DealCustomFieldsDictionaryStrings
{
	public const string StringOne = "doesnt_really_matter";
	public const string StringTwo = "not_important";
}


[JsonObject]
public class WithSimilarNamedProperties
{
	[JsonProperty(DealCustomFieldsDictionaryStrings.StringOne)]
	public DateTime? Blurb
	{
		get;
		set;
	}

	[JsonProperty(DealCustomFieldsDictionaryStrings.StringTwo)]
	public bool BlurbSpecified
	{
		get;
		set;
	}
}


[JsonObject]
public class WithDifferentNamedProperties
{
	[JsonProperty(DealCustomFieldsDictionaryStrings.StringOne)]
	public DateTime? Xyz
	{
		get;
		set;
	}

	[JsonProperty(DealCustomFieldsDictionaryStrings.StringTwo)]
	public bool Abc
	{
		get;
		set;
	}
}


public class Program
{
	public static void Main()
	{
		var date =  DateTime.Now;
		
		var withSimilarNameProperties= new WithSimilarNamedProperties(){Blurb =date};
		var jsonWithSimilarNameProperties= JsonConvert.SerializeObject(withSimilarNameProperties);
		var objWithSimilarNameProperties= JsonConvert.DeserializeObject<WithSimilarNamedProperties>(jsonWithSimilarNameProperties);
				
		var withDifferentNamedProperties = new WithDifferentNamedProperties(){Xyz = date};
		var jsonWithDifferentNamedProperties = JsonConvert.SerializeObject(withDifferentNamedProperties );			
		var objDifferentNamedProperties = JsonConvert.DeserializeObject<WithDifferentNamedProperties>(jsonWithDifferentNamedProperties);
		
	 
	 Console.WriteLine("WithSimilarNamedProperties - Doesn't deserialise properly: ("+withSimilarNameProperties.Blurb+") (" +objWithSimilarNameProperties.Blurb +")");
     Console.WriteLine("WithDifferentNamedProperties - Deserialises properly     : ("+withDifferentNamedProperties.Xyz+") (" +objDifferentNamedProperties.Xyz+")");	
		
	}
}

nadsmoo avatar May 11 '20 16:05 nadsmoo

This isn't a bug, it's by-design - it's just under-documented:

New feature - Added XmlSerializer style Specified property support

Confounding things, the current documentation page for Conditional Property Serialization describes using a bool-returning method, not a property, even though it's idomatic with XmlSerializer to use properties not methods.

See also:

  • https://stackoverflow.com/questions/39223335/how-to-force-newtonsoft-json-to-serialize-all-properties-strange-behavior-with

daiplusplus avatar Nov 09 '23 04:11 daiplusplus