2

I'm using the ShouldSerialize method to conditionally serialize a field when I use XmlSerializer. But now I need to serialize the same class using JSON, but I would like the ShoulSerialize method to be ignored when using JSON, can I do this in any way?

[TestClass]
public class UnitTest1
{
    private readonly Customer _customer = new Customer
        {
            FirstName = "Paulo",
            LastName = "Balbino",
            Age = 25
        };

    [Serializable]
    public class Customer
    {
        [XmlElement("FirstName")]
        public string FirstName { get; set; }

        [XmlElement("LastName")]
        public string LastName { get; set; }

        [XmlElement("Age")]
        public int Age { get; set; }

        public bool ShouldSerializeLastName()
        {
            return Age > 30; // Enter here only if it is XmlSerialize.
        }
    }

    [TestMethod]
    public void XmlSerialize()
    {
        try
        {
            var xmlSerializer = new XmlSerializer(typeof(Customer));

            using (var textWriter = new StringWriter())
            {
                xmlSerializer.Serialize(textWriter, _customer);
                Debug.WriteLine(textWriter.ToString());
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }

    [TestMethod]
    public void JsonConvert()
    {
        try
        {
            var json = Newtonsoft.Json.JsonConvert.SerializeObject(_customer);
            Debug.WriteLine(json);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }
}

Result Xml:

<?xml version="1.0" encoding="utf-16"?>
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Paulo</FirstName>
  <Age>25</Age>
</Customer>

Result Json:

{"FirstName":"Paulo","Age":25}

Both go to the ShouldSerializeLastName() method, however, I'd like it to be ignored in JSON and all fields would be displayed.

dbc
  • 104,963
  • 20
  • 228
  • 340
Paulo Balbino
  • 243
  • 1
  • 14
  • JSON serialization (using Newtonsoft.Json, or something else), doesn't use the `ShouldSerialize[Property]` method, it is used by `XmlSerializer`. You can, if you're using Newtonsoft.Json, create a custom converter and do some things to use these methods. – jeuxjeux20 Jan 10 '19 at 19:05
  • I edited the code, in the tests I performed both pass through the method. – Paulo Balbino Jan 11 '19 at 10:19
  • 1
    @jeuxjeux20 - actually Json.NET does honor the `ShouldSerialize[Property]` as explained in https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm#ShouldSerialize – dbc Jun 26 '19 at 21:44

1 Answers1

2

You can disable Json.NET's support for ShouldSerialize*() conditional serialization by using your own contract resolver and setting DefaultContractResolver.IgnoreShouldSerializeMembers = true.

First, allocate a contract resolver as follows:

static DefaultContractResolver IgnoreShouldSerializeContractResolver = new DefaultContractResolver
{
    IgnoreShouldSerializeMembers = true,
    //Set other properties as required, e.g.:
    //NamingStrategy = new CamelCaseNamingStrategy(),
};

Then use it as follows:

var settings = new JsonSerializerSettings
{
    ContractResolver = IgnoreShouldSerializeContractResolver,
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(_customer, settings);

Notes:

  • You may want to cache the contract for best performance, as it generates contract information for each type only once, then caches it.

  • Because the contract resolver caches type information, modifying properties of a pre-existing contract resolver after it has been constructed and used to generate contracts is not recommended.

  • IgnoreShouldSerializeMembers was introduced in Json.NET 11.0.1.

Sample fiddle here.

dbc
  • 104,963
  • 20
  • 228
  • 340