Serializing and Deserializing XmlDocument in WCF with DataContractSerializer

I have a WCF service that takes a string as a parameter for one of its contracts. However, this line contains xml content.

I need to convert this to a class marked as DataContract but not exposed to the outside world.

I need to use a DataContractSerializer because the members of the class have the [DataMember] set to a different name. For example: the Phone property is named DataMember Name as "Telephone" , so when I deserialize xmldocument using a regular serializer, I get an error because the deserializer is looking for a Phone element that does not exist.

How to remove serialization of XmlDocument using DataContractSerializer ? One limitation, however, I cannot save xmldocument to a file.

EDIT : Found a great article on serialization and de-serialization with the DataContractSerializer here.

My client code:

 string xmldata = "<Customer> + System.Environment.NewLine+ "<Age>1</Age>"+ System.Environment.NewLine+ "<BirthDate>1900-01-01T01:01:01.0000000-05:00</BirthDate>" + System.Environment.NewLine+ "<FistName>John</FistName>"+ System.Environment.NewLine + "<LastName>Doe</LastName>" + System.Environment.NewLine + "</Customer>"; doc.LoadXml(xmldata); Service1Client a = new Service1Client(); a.GetData(doc.OuterXml.ToString()); 

My service code:

 public string GetData(string per) { string xmldata = per; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmldata); XmlDemo.Person a = Person.Create(); DataContractSerializer ser = new DataContractSerializer(a.GetType()); StringWriter stringWriter = new StringWriter(); XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter); xmlDoc.WriteTo(xmlWriter); MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(stringWriter.ToString())); stream.Position = 0; XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); Person myContact = (Person)ser.ReadObject(reader, true); return string.Empty; } 

My DataContract:

 [Serializable] [DataContract(Name = "Customer")] public class Person { private Person() {} [DataMember(Name = "FistName")] public string FName { get; set; } [DataMember(Name = "LastName")] public string LName { get; set; } [DataMember(Name = "Age")] public int Age { get; set; } [DataMember(Name = "BirthDate")] public DateTime DOB { get; set; } public static Person Create() { return new Person(); } } 

I get this error in Person myContact = (Person) ser.ReadObject (reader, true);

  Error in line 1 position 11. Expecting element 'Customer' from namespace 'http://schemas.datacontract.org/2004/07/XmlDemo' .. Encountered 'Element' with name 'Customer', namespace ''.
+4
source share
2 answers

Disable the straight path

 MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes("<myXml />")); stream.Position = 0; XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); MyContact myContact = (MyContact)ser.ReadObject(reader, true); 

Remove from XmlDocument

 StringWriter stringWriter = new StringWriter(); XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter); xmlDoc.WriteTo(xmlWriter); MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(stringWriter.ToString())); stream.Position = 0; XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); MyContact myContact = (MyContact)ser.ReadObject(reader, true); 
+2
source

Is this your service? If this is the case, then do not send or receive XML in the string parameter, as these are not the same thing.

Also, although you did not expose the DataContract into which you want to deserialize this XML into the world, you pretty much did it by exposing the XML. This is pretty much the same effect. So instead, you should create a DataContract class that has no behavior associated with it, and then output it to your ServiceContract. If you need to use it as data in a behavior class, copy the data to a new instance of your inner class that you never expose.


I still recommend that you stop this nonsense when copying XML to and from strings. However, based on the code and the exception you posted:

Why do this

 XmlDemo.Person a = Person.Create(); 

and then destroy it during deserialization?

XmlDemo.Person a;

is adequate. Then use typeof (XmlDemo.Person) instead of a.GetType ().

Also, is the Person class you sent the same class to "XmlDemo.Person"? I am very curious to know where this namespace comes from. To remove my ambiguity, try changing the [DataContract] attribute to say Namespace = String.Empty (or possibly Namespace = null).

Finally, have you ever heard of a developer who did not call Dispose on class instances that implement IDisposable?

+1
source

All Articles