XSerializer icon indicating copy to clipboard operation
XSerializer copied to clipboard

Serializing a List causes EmitNull to be always b True

Open hutchcodes opened this issue 7 years ago • 0 comments

When serializing a List of objects EmiNil gets set to true for all child objects.

This test highlights the inconsistent behavior:

public class ParentObject
{
    public ChildObject Child { get; set; }
}

public class ChildObject
{
    [XmlElement(ElementName = "ITEM1")]
    public string Item1 { get; set; }

    [XmlElement(ElementName = "ITEM2")]
    public string Item2 { get; set; }
}

[Test]
public void WhenEmitNilOptionIsNotSetDontEmitNilInLists()
{
    var parentList = new List<ParentObject>
        {
            new ParentObject { Child = new ChildObject { Item1 = "TestValue" } }
        };

    var serializerWorks = new XmlSerializer<ParentObject>(options => options.Indent());
    var xmlWorks = serializerWorks.Serialize(parentList.First());

    Assert.That(xmlWorks, Contains.Substring("<ITEM1"));
    Assert.That(xmlWorks, !Contains.Substring("<ITEM2"));

    var serializerBug = new XmlSerializer<List<ParentObject>>(options => options.Indent());
    var xmlBug = serializerBug.Serialize(parentList);

    Assert.That(xmlBug, Contains.Substring("<ITEM1"));
    Assert.That(xmlBug, !Contains.Substring("<ITEM2"));
}

xmlWorks will not have any reference to Item2, but xmlBug will contain <ITEM2 xsi:nil="true" />.

I followed this down to line:30 of ListSerializer.cs where we add .AlwaysEmitNil() to the options. That doesn't feel to me like ht right thing to do since we haven't specified that we want nil emitted, but there may be some history to that because when I tried removing that, it caused about 10 tests to fail.

Maybe we could add a NeverEmitNil() option at the same level as EmitNil(), and use that setting to override .AlwaysEmitNil().

If that sounds good, I can submit a pull request.

hutchcodes avatar Nov 19 '18 19:11 hutchcodes