ulu
ulu

Reputation: 6092

Custom XML serialization for a single property

I want to serialize all properties of type string[] as CSV.

For example, given a class:

public class Choice {
    [XmlAttribute]
    public string[] Options { get; set; }
}

and the following serialization code:

var choice = new Choice() { Options = new[] {"op 1", "op 2"}};
var serializer = new XmlSerializer(typeof(Choice));
var sb = new StringBuilder();
serializer.Serialize(new StringWriter(sb), choice);
Console.WriteLine(sb);

I have the following output:

<Choice xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Options="op 1 op 2" />

Note the Options="op 1 op 2" part. If I deserialize the output, the value is split into 4 strings, giving me 4 array elements instead of 2 that were there originally.

What I want is to be able to run a custom code for this particular property (or for any property of type string[]), so that I control the output. I don't want to override the serialization process for the whole class.

If this is impossible or too hard to implement with the default Microsoft Serializer, I'll be happy to consider a better alternative.

Upvotes: 1

Views: 2616

Answers (1)

Dave M
Dave M

Reputation: 3033

If it doesn't absolutely have to be an attribute, then simply change [XmlAttribute] to [XmlElement]

public class Choice
{
    [XmlElement]
    public string[] Options { get; set; }
}

I would highly recommend the above solution since the serialized xml is much cleaner and more exact, and you are relying on the XmlSerializer backend to do all the parsing and not relying on rolling your own custom parsing. If you absolutely must have it as an attribute you can ignore the Options property and wrap it with another property that does the custom parsing:

public class Choice
{
    [XmlIgnore]
    public string[] Options { get; set; }

    [XmlAttribute("Options")]
    public string OptionsSerialized
    {
        get { return ToCsv(Options); }
        set { Options = FromCSV(value); }
    }

    private string ToCsv(string[] input)
    {
       //implementation here
    }

    private string[] FromCsv(string[] input)
    {
       //implementation here
    }
}

Upvotes: 1

Related Questions