views:

603

answers:

4

I'm serializing a class like this

public MyClass
{
    public int? a { get; set; }
    public int? b { get; set; }
    public int? c { get; set; }
}

All of the types are nullable because I want minimal data stored when serializing an object of this type. However, when it is serialized with only "a" populated, I get the following xml

<MyClass ...>
    <a>3</a>
    <b xsi:nil="true" />
    <c xsi:nil="true" />
</MyClass>

How do I set this up to only get xml for the non null properties? The desired output would be

<MyClass ...>
    <a>3</a>
</MyClass>

I want to exclude these null values because there will be several properties and this is getting stored in a database (yeah, thats not my call) so I want to keep the unused data minimal.

+2  A: 

You ignore specific elements with specification

public MyClass
{
    public int? a { get; set; }

    [System.Xml.Serialization.XmlIgnore]
    public bool aSpecified { get { return this.a != null; } }

    public int? b { get; set; }
    [System.Xml.Serialization.XmlIgnore]
    public bool bSpecified { get { return this.b != null; } }

    public int? c { get; set; }
    [System.Xml.Serialization.XmlIgnore]
    public bool cSpecified { get { return this.c != null; } }
}

The {field}Specified properties will tell the serializer if it should serialize the corresponding fields or not by returning true/false.

Allen
note: I answered this because honestly, I'm looking for a better solution, I'm not a big fan of all these extra fields as my class has SEVERAL fields to serialize
Allen
I may have misunderstood your 'bonus', but null strings are automatically omitted, without the xsi:nil="true" flotsam.
Jeff Sternal
@Jeff, Ah, so they are :-P Thanks
Allen
No problem - and incidentally, I hope someone more ingenious than me comes up with a more elegant workaround than the specification pattern. :)
Jeff Sternal
+2  A: 

I suppose you could create an XmlWriter that filters out all elements with an xsi:nil attribute, and passes all other calls to the underlying true writer.

Martin v. Löwis
I like it, very simple, great idea :)
Allen
A: 

The simplest way of writing code like this where the exact output is important is to:

  1. Write an XML Schema describing your exact desired format.
  2. Convert your schema to a class using xsd.exe.
  3. Convert your class back to a schema (using xsd.exe again) and check it against your original schema to make sure that the serializer correctly reproduced every behaviour you want.

Tweak and repeat until you have working code.

If you are not sure of the exact data types to use initially, start with step 3 instead of step 1, then tweak.

IIRC, for your example you will almost certainly end up with Specified properties as you have already described, but having them generated for you sure beats writing them by hand. :-)

Christian Hayter
+1  A: 

Have you read SO: Serialize a nullable int ?

Rubens Farias