Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent <xsi:nil="true"> on Nullable Value Types when Serializing to XML

I have added some nullable value types to my serializable class. I perform a serialization using XmlSerializer but when the value is set to null, I get an empty node with xsi:nil="true". This is the correct behaviour as I have found at Xsi:nil Attribute Binding Support.

Is there a way to switch off this option so that nothing is output when the value type is null?

like image 772
Ryall Avatar asked Feb 12 '10 14:02

Ryall


4 Answers

I had to add a ShouldSerialize method to each nullable value.

[Serializable]
public class Parent
{
    public int? Element { get; set; }

    public bool ShouldSerializeElement() => Element.HasValue;
}
like image 152
Todd Skelton Avatar answered Jan 01 '23 21:01

Todd Skelton


I've had the same problem.. here's one of the places i read about handling nullable value types while serializing to XML: http://stackoverflow.com/questions/244953/serialize-a-nullable-int

they mention about using built-in patterns like creating additional properties for nullable value types. like for a property named

public int? ABC

you must either add either public bool ShouldSerializeABC() {return ABC.HasValue;} or public bool ABCSpecified { get { return ABC.HasValue; } }

i was only serializing to xml to send to a sql stored proc, so me too has avoided changing my classes. I'm doing a [not(@xsi:nil)] check on all the nullable elements in my .value() query.

like image 36
Chin Avatar answered Jan 01 '23 22:01

Chin


This is probably the least sophisticated answer, but I solved it for me whith a simple string replace.

.Replace(" xsi:nil=\"true\" ", "");

I'm serializing to string first anyway. I can save to file later.

It keeps all my XmlWriterSettings intact. One other solution I found her messed it up:)

    private static string Serialize<T>(T details)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var ms = new MemoryStream())
        {
            var settings = new XmlWriterSettings
            {
                Encoding = Encoding.GetEncoding("ISO-8859-1"),
                NewLineChars = Environment.NewLine,
                ConformanceLevel = ConformanceLevel.Document,
                Indent = true,
                OmitXmlDeclaration = true
            };

            using (var writer = XmlWriter.Create(ms, settings))
            {
                serializer.Serialize(writer, details);
                return Encoding.UTF8.GetString(ms.ToArray()).Replace(" xsi:nil=\"true\" ", "");
            }
        }
    }
like image 28
Steffen Nordquist Avatar answered Jan 01 '23 21:01

Steffen Nordquist


I found that the public bool ABCSpecified was the only one that worked with .NET 4.0. I also had to add the XmlIgnoreAttribute

Here was my complete solution to suppress a String named ABC in the Web Reference Resource.cs file:

// backing fields
private string abc;
private bool abcSpecified; // Added this - for client code to control its serialization

// serialization of properties
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string ABC
{
    get
    {
        return this.abc;
    }
    set
    {
        this.abc= value;
    }
}

// Added this entire property procedure
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ABCSpecified
{
    get
    {
        return this.abcSpecified;
    }
    set
    {
        this.abcSpecified = value;
    }
}
like image 25
Rod Wittmier Avatar answered Jan 01 '23 21:01

Rod Wittmier