How to serialize/deserialize a C# WCF DataContract to/from XML
Asked Answered
Z

3

13

I am developing a WCF service which will be consumed by multiple different client applications. In order to make one functionality work, the server needs to read an XML file into a C# DataContract which is then passed on to the concerned client. As far as I understand from the MSDN website, this is possible but I couldn't find any complete examples. In particular, the website talks about a 'stream' parameter which I don't quite get yet.

My data contract has one property field which is a list of another data contract which has multiple simple property fields.

e.g.

    [DataContract]
    public class MyClass1 {
        [DataMember]
        public string name;
        [DataMember]
        public int age;
    }

    [DataContract]
    public class MyClass2 {
        [DataMember]
        public List<MyClass1> myClass1List;
    }

My classes look something like this.

Zonnya answered 21/6, 2012 at 16:8 Comment(1)
duplicate: #4859298Kinsella
L
15

Here is an example

MyClass1 obj = new MyClass1();
DataContractSerializer dcs = new DataContractSerializer(typeof(MyClass1));

using (Stream stream = new FileStream(@"C:\tmp\file.xml", FileMode.Create, FileAccess.Write))
{
    using (XmlDictionaryWriter writer = 
        XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8))
    {
        writer.WriteStartDocument();
        dcs.WriteObject(writer, obj);
    }
}

Books b = new Books();

DataContractSerializer dcs = new DataContractSerializer(typeof(Books));

try
{
    Stream fs = new FileStream(@"C:\Users\temelm\Desktop\XmlFile.xml", FileMode.Create, FileAccess.Write);

    XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateTextWriter(fs, Encoding.UTF8);
    xdw.WriteStartDocument();
    dcs.WriteObject(xdw, b);
    xdw.Close();
    fs.Flush();
    fs.Close();
}
catch (Exception e)
{
    s += e.Message + "\n";
}
Loading answered 21/6, 2012 at 16:11 Comment(10)
@KirkWoll what does <writer.WriteStartDocument()> do? and what if I only want to append 1 element to the XML file?Zonnya
[from metadata] - When overridden in a derived class, writes the XML declaration with the version "1.0". And this code writes only 1 object to the file, if that's what you mean.Loading
it writes one object but that object is a list of other objects so it's fine. how about reading an existing XML document into a datacontract. any ideas?Zonnya
Never mind, I got it both working. Thanks a lot, I appreciate it. :)Zonnya
When I try to declare the FileStream and XmlDictionaryWriter without the 'using's it does not write the xml file. any ideas?Zonnya
yes - the dispose/close methods flush the file back to disk, don't remove the usingsLoading
i understand that the using concept but i manually flush the FileStream and close it. still does not work. I am actually really curious why it doesn't work :D apart from the disposal is there something else done?Zonnya
nope, are you sure you flush/close/dispose the writer and the stream in the same order as in my example? note there are 2 nested usingsLoading
I added a block of code at the end of the question. I am not closing the writer..Zonnya
yes, I added your code to the answer - you were missing the line to close the writer - you have to do this, otherwise the data you've written to it stays in its buffer and doesn't get flushed to the streamLoading
P
2

This can be useful for you. When you need XElement. For instance when you going append node to XDocument or replece XElement of this document.

private XElement objectToXElement(SomeContractType obj)
        {
            DataContractSerializer dcs = new DataContractSerializer(typeof(SomeContractType);

            var ms = new MemoryStream();
            var xw = XmlWriter.Create(ms);
            dcs.WriteObject(xw, obj);
            xw.Flush();
            xw.Close();
            ms.Position = 0;
            XElement xe = XElement.Load(ms);

            return xe;
        }
Pacifier answered 7/11, 2016 at 8:19 Comment(0)
V
0

There is the NetDataContractSerializer which solves a whole bunch of problems when using WCF.

See here MSDN NetDataContractSerializer

It is typically used for wrapping all kinds of objects and pass it over WCF.

You can use it for wrapping objects into a byte[] and transport it over WCF, on the serverside, you can easily Deserialize the objects and do whatever you want with them.

Here is a discussion on how to use this Serializer correctly: MSDN Social

Code snippets are provided there also!

Volvulus answered 21/6, 2012 at 16:14 Comment(1)
WTF, a link to the GERMAN Microsoft site??? you probablye meant: msdn.microsoft.com/library/…Cupola

© 2022 - 2024 — McMap. All rights reserved.