Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to make DataContractSerializer output cleaner XML?

Using the DataContractSerializer to serialize my object I get an output similar to

 <?xml version="1.0" encoding="utf-8" ?> 
 <AgentNotification xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/The.name.space.Notifications">
  <_x003C_Created_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
  <_x003C_Id_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" />        
 <_x003C_Email_x003E_k__BackingField>[email protected]</_x003C_Email_x003E_k__BackingField> 
  <_x003C_Name_x003E_k__BackingField>Random Person</_x003C_Name_x003E_k__BackingField> 
 <_x003C_Policies_x003E_k__BackingField>
 <PolicyNotification>
  <_x003C_Created_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
  <_x003C_Id_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
  <_x003C_ConfirmationNumber_x003E_k__BackingField>Some number</_x003C_ConfirmationNumber_x003E_k__BackingField>   
  </PolicyNotification>
 <PolicyNotification>
  </_x003C_Policies_x003E_k__BackingField>  
  </AgentNotification>

Is there any way for it to output tags that are just

<Id>
<Name>

etc, without the need to cover my classes with attributes?

If there's not a way the output of this is guaranteed to be the same every time correct? So that if I use this to render my object graphs are XML to mash up with an X* document for file generation that I'll never run into an issue where my nodes change names and the document comes out blank correct?

like image 221
Chris Marisic Avatar asked Dec 23 '09 16:12

Chris Marisic


2 Answers

This is happening because you must have marked your types (e.g. AgentNotification) with [Serializable]. When DataContractSerializer encounters a type marked with [Serializable] but no explicit [DataContract], it generates a default contract for the type that matches how BinaryFormatter serializes a class, which is to serialize all member variables of a class — even variables marked as private — by name. For auto-implemented properties, this means the secret backing fields get serialized by name; their names are the peculiar element names you are seeing.

The easiest way to solve this is to remove the [Serializable] attribute from your classes. You almost certainly don't need it unless you are actually using BinaryFormatter or SoapFormatter. Having done so, DataContractSerializer will now serialize your public properties and fields by name, rather than public and private fields by name.

like image 66
dbc Avatar answered Oct 11 '22 13:10

dbc


The long element names (such as, _x003C_Created_x003E_k__BackingField) are created by .NET when you use autoproperties.

If you changed them to properties with backing fields, they would instead use your backing field names. You can do that without adding any attributes to your code.

(Beyond that, simply adding a [DataContract] attribute to your class definition will tidy up your XML a lot -- though not completely.)

like image 42
David White Avatar answered Oct 11 '22 12:10

David White