views:

1300

answers:

2

I am having a look into using the DataContractSerializer and I'm having trouble getting the right output format. The DataContractSerializer serializes the following class

[DataContract(Name = "response")]
public class MyCollection<T> 
{
    [DataMember]
    public List<T> entry { get; set; }
    [DataMember]
    public int index { get; set; }
}

Into

<response><entry><T1>object1</T1><T2>object2</T2></entry><index></index></response>

But what I want is

<response><entry><T1>object1</T1></entry><entry><T2>object2</T2></entry><index></index></response>

How do I do this with the DataContractSerializer? But also maintain the first output for DataContractJsonSerializer?

+1  A: 

If you are writing xml, I wonder whether xml serializer wouldn't be a better choice (it has more granular control over the names, etc).

The problem, though, is that XmlSerializer isn't always the biggest fan of generics...

Additionally - having tried a few options involving [XmlArray] / [XmlArrayItem] etc... it looks very hard to get it to the format you want... plus it isn't easy to guess what you mean by the T1 / T2 - but the following may come close:

[XmlRoot("response")]
public class MyResponse : MyCollection<int> { }

[DataContract(Name = "response")]
public class MyCollection<T>
{
    [DataMember]
    [XmlElement("entry")]
    public List<T> entry { get; set; }
    [DataMember]
    public int index { get; set; }
}

This has both XmlSerializer and DataContractSerializer attributes, but I had to lose the generics in the type we use for the response (hence the "closed" MyResponse type)

Marc Gravell
T1, T2 as in the items in "entry" ... let me try that out..... The problem is lists gets serialized as <listname><item1><item2></listname> but I want <listname><item1></listname><listname><item2></listname>
seanlinmt
The use of [XmlElement] on the list does exactly that.
Marc Gravell
Ok... that doesn't seem to work out... I'm going to have a look at http://www.albahari.com/nutshell/ch15.aspx again but 1 more day and I can't get a solution I guess I will use XmlSerializer for serializing to XML and ATOM. Or use surrogates...
seanlinmt
Hmm the [XmlElement("entry")] doesn't seem to make a difference. I haven't figured out how to incorporate the [XmlRoot("response")] though. I need the generics.
seanlinmt
It does make a difference, but you have to use XmlSerializer
Marc Gravell
+2  A: 

Hi,

Based on this article, it seems that DataContractSerializer does not have support for customizing the resultant xml.

http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/

From the MS site there is an important note: 'The DataContractAttribute attribute should not be applied to classes that already implement the ISerializable interface or that are marked with the SerializableAttribute. An exception is thrown if you try to serialize an instance of such a type.'

PS: Sorry I couldn't post the second link, but the engine does not allow post more than one link to new users.

Regards, Herberth

Right. This is not what the DataContractSerializer is for. If you need detailed control over the XML, then you need the XmlSerializer.
John Saunders