I have a serialized object in a string that was serialized by the XmlSerializer. I would like to deserialize it using the DataContractSerializer.
This code produces an empty object:
Dim Enc As New UTF8Encoding
Using Stream As New MemoryStream(Enc.GetBytes(rec.XML))
Dim xtr As New XmlTextReader(Stream)
Dim Formatter As New DataContractSerializer(GetType(SMTPSettings))
smtp = Formatter.ReadObject(xtr, False)
End Using
This is the string:
<?xml version="1.0"?>
<SMTPSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Host>mail.clubcompete.com</Host>
<Port>26</Port>
<UserName>[email protected]</UserName>
<Password>xxxxxxxxx</Password>
<UseSSL>false</UseSSL>
<TestEmailAddress>[email protected]</TestEmailAddress>
</SMTPSettings>
How do I deserialize the string using the DataContractSerializer? I cannot use the XmlSerializer because it creates DLLs in my server temp folder and the web host will not allow it.
You don't show your class
SMTPSettings, so I will guess it looks something like this:If you wish to deserialize the XML shown in your question to this class using
DataContractSerializer, you need to keep the following differences withXmlSerializerin mind:DataContractSerializerdoes not support XML attributes (other than namespace attributes and specialized attributes such asxsi:type). See here for confirmation.Luckily your XML does not contain such attributes.
DataContractSerializerdoes not support serializing collections without an outer container element.Luckily your XML does not contain repeating elements without an outer container, so this does not apply.
Default namespaces are inferred differently.
XmlSerializerassumes that a type is serialized in the empty XML namespace unless an attribute such asXmlRootAttribute.Namespaceis applied.DataContractSerializerassumes that a type is serialized in a nonempty XML namespace by default, specificallyhttp://schemas.datacontract.org/2004/07/Clr.Namespace. For confirmation see Data Contract Namespaces.Since your XML is not in any namespace, you will need to apply data contract attrtibutes to your type to specify an empty namespace.
Elements must be ordered.
XmlSerializerallows elements to be in an any order, butDataContractSerializerrequires the elements to be in a specific order. See Data Member Order for details. If you don't specify an order by using data contract attributes, the data contract serializer assumes that the elements should be serialized alphabetically.Since your XML elements are not in alphabetic order, once again you will need to use data contract attributes to specify the required order.
Putting all that together, the following version of
SMTPSettingscan be used to deserialize that XML sample:Demo fiddle #1 (in c#) here.
Given all the restrictions of
DataContractSerializer, you might consider just loading your class into a LINQ to XMLXElementand populating yourSMTPSettingsmanually like so:This completely avoids having to fuss with element order.
Demo fiddle #2 here.