views:

553

answers:

2

I have classes like this

[DataContract(Namespace = "")]
public class Foo
{
    [DataMember(Order = 0)]
    Bar bar;
}

[DataContract(Namespace = "")]
public class Bar
{
    Baz baz;

    [DataMember(Order = 0)]
    string TheBaz
    {
        get { baz.ToString(); }
        set { SomeOtherCode(value); }
    }
}

I want this to generate XML like this

<Foo>
    <Bar>String from baz.ToString()</Bar>
</Foo>

but am getting something more like:

<Foo>
    <Bar><TheBaz>String from baz.ToString()</TheBaz></Bar>
</Foo>

is it possible to fix this? This artical says that one of the disadvantages of DataContractSerializer is:

  1. No control over how the object is serialized outside of setting the name and the order

leading me to wonder is this is not a solvable problem.


I known this can be done with IXmlSerializable and ReadXml/WriteXml because I'm supposed to be removing code that does just that.

+1  A: 

Implement IXmlSerializable on the Bar class, and then have it output <Bar>String from baz.ToString()</Bar> when serialized.

You can leave the Foo class as is, and the DataContractSerializer will take care of the rest.

casperOne
But how would you deal with additional properties in the "Bar" class in this scenario?
marc_s
That is *exactly* the code I have been tacked with getting rid of :)
BCS
casperOne
That is doing things the hard way...
Marc Gravell
@Marc Gravell: I would disagree here. With your method, you have to have two sets of tests for two pieces of code which do the same thing and you always have to keep those in sync. With mine, you have two separate pieces of code which do two separate things, with separate outcomes.
casperOne
A: 

I realized my first answer was completely bogus - but you can cheat with properties:

[DataContract(Namespace = "")]
public class Foo
{
    [DataMember(Order = 0, Name="Bar")]
    private string BazString {
        get {
            return bar == null ? null : bar.TheBaz.ToString();
        }
        set {
            if(value == null) {
                bar = null;
            }
            else {
                if(bar == null) bar = new Bar();
                bar.TheBaz = value;
            }
        }
    }

    Bar bar;
}
Marc Gravell