Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output of DataContractSerializer differs between .NET and Mono

I am serializing data in a Mono For Android application and sending it using REST to a .NET server listening using WCF. So far this has worked fine, however, with this particular data contract, although the server throws no errors, the Lists inside the data contract show up as empty.

Using Fiddler and creating two projects with the same code, I was able to compare the normal .NET DataContractSerializer output with the output from Mono's implementation of DataContractSerializer.

.NET output:

<VisitDataContractEx xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts">   <_isDirty xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">true</_isDirty>   <_id xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.Domain" xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:internalValue>a7b97b48-d3a9-419d-9f4e-330ffc7a01ee</d2p1:internalValue>   </_id>   <_key xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">false</_key>   <_keyIdentifier xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">SurrogateKey</_keyIdentifier>   <ChecklistComplete>false</ChecklistComplete>   <Date>2013-03-05T15:43:49.5008406+02:00</Date>   <GpsAccuracy>1</GpsAccuracy>   <GpsLatitude>1</GpsLatitude>   <GpsLongitude>1</GpsLongitude>   <OrderComplete>false</OrderComplete>   <PhotoComplete>false</PhotoComplete>   <StockComplete>false</StockComplete>   <Sync>2013-03-05T15:43:49.5468406+02:00</Sync>   <checkListAnswers xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_list>       <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU>         <d2p1:_dataContract z:Id="i2">           <d2p1:_isDirty>true</d2p1:_isDirty>           <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain">             <d6p1:internalValue>95ae919b-a389-4ea7-a009-af1b91890c36</d6p1:internalValue>           </d2p1:_id>           <d2p1:_key>false</d2p1:_key>           <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier>           <Answer>false</Answer>           <checkListQuestion>             <d2p1:_dataContract i:nil="true" />             <d2p1:_description i:nil="true" />             <d2p1:_hasDataContract>false</d2p1:_hasDataContract>             <d2p1:_id xmlns:d7p1="http://schemas.datacontract.org/2004/07/Organization.Domain">               <d7p1:internalValue>176cbb31-7df2-4966-baa9-4e3cd2a0c6d5</d7p1:internalValue>             </d2p1:_id>           </checkListQuestion>         </d2p1:_dataContract>         <d2p1:_description i:nil="true" />         <d2p1:_hasDataContract>true</d2p1:_hasDataContract>         <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain">           <d5p1:internalValue>95ae919b-a389-4ea7-a009-af1b91890c36</d5p1:internalValue>         </d2p1:_id>       </d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU>     </d2p1:_list>   </checkListAnswers>   <comments xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_list />   </comments>   <directSalesAgent xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_dataContract i:nil="true" />     <d2p1:_description i:nil="true" />     <d2p1:_hasDataContract>false</d2p1:_hasDataContract>     <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain">       <d3p1:internalValue>6f99f86a-5b1b-4f73-bdc3-388e0b7cf417</d3p1:internalValue>     </d2p1:_id>   </directSalesAgent>   <directSalesAgentSuperVisor xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_dataContract i:nil="true" />     <d2p1:_description i:nil="true" />     <d2p1:_hasDataContract>false</d2p1:_hasDataContract>     <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain">       <d3p1:internalValue>d57db20d-9b3a-4345-849e-d5a0d0d88f70</d3p1:internalValue>     </d2p1:_id>   </directSalesAgentSuperVisor>   <photos xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_list>       <d2p1:IdentityDataReferenceOfPhotoDataContractExX8I0_S_SPU>         <d2p1:_dataContract z:Id="i3">           <d2p1:_isDirty>true</d2p1:_isDirty>           <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain">             <d6p1:internalValue>3db431e9-3338-4c96-aea9-d833eb0dc8ae</d6p1:internalValue>           </d2p1:_id>           <d2p1:_key>false</d2p1:_key>           <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier>           <Content i:nil="true" />           <Taken>2013-03-05T15:43:49.4748406+02:00</Taken>         </d2p1:_dataContract>         <d2p1:_description i:nil="true" />         <d2p1:_hasDataContract>true</d2p1:_hasDataContract>         <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain">           <d5p1:internalValue>3db431e9-3338-4c96-aea9-d833eb0dc8ae</d5p1:internalValue>         </d2p1:_id>       </d2p1:IdentityDataReferenceOfPhotoDataContractExX8I0_S_SPU>     </d2p1:_list>   </photos>   <salesPoint xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_dataContract i:nil="true" />     <d2p1:_description i:nil="true" />     <d2p1:_hasDataContract>false</d2p1:_hasDataContract>     <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain">       <d3p1:internalValue>692a294a-2d1b-4026-9693-0c0ce552a2fb</d3p1:internalValue>     </d2p1:_id>   </salesPoint>   <stockCounts xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts" i:nil="true" /> </VisitDataContractEx> 

Mono Output:

<VisitDataContractEx xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts">   <_isDirty xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">true</_isDirty>   <_id xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.Domain" xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:internalValue>9297eea9-82af-4981-ab9d-40aa0ac0fa0d</d2p1:internalValue>   </_id>   <_key xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">false</_key>   <_keyIdentifier xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">SurrogateKey</_keyIdentifier>   <ChecklistComplete>false</ChecklistComplete>   <Date>2013-03-05T17:49:06.362243+02:00</Date>   <GpsAccuracy>1</GpsAccuracy>   <GpsLatitude>1</GpsLatitude>   <GpsLongitude>1</GpsLongitude>   <OrderComplete>false</OrderComplete>   <PhotoComplete>false</PhotoComplete>   <StockComplete>false</StockComplete>   <Sync>2013-03-05T17:49:06.438934+02:00</Sync>   <checkListAnswers xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_list>       <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx>         <d2p1:_dataContract xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" z:Id="i2">           <d2p1:_isDirty>true</d2p1:_isDirty>           <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain">             <d6p1:internalValue>75083457-9714-4971-b60c-f28fa43167ad</d6p1:internalValue>           </d2p1:_id>           <d2p1:_key>false</d2p1:_key>           <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier>           <Answer>false</Answer>           <checkListQuestion xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">             <d6p1:_dataContract xmlns:d7p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" />             <d6p1:_description i:nil="true" />             <d6p1:_hasDataContract>false</d6p1:_hasDataContract>             <d6p1:_id xmlns:d7p1="http://schemas.datacontract.org/2004/07/Organization.Domain">               <d7p1:internalValue>176cbb31-7df2-4966-baa9-4e3cd2a0c6d5</d7p1:internalValue>             </d6p1:_id>           </checkListQuestion>         </d2p1:_dataContract>         <d2p1:_description i:nil="true" />         <d2p1:_hasDataContract>true</d2p1:_hasDataContract>         <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain">           <d5p1:internalValue>75083457-9714-4971-b60c-f28fa43167ad</d5p1:internalValue>         </d2p1:_id>       </d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx>     </d2p1:_list>   </checkListAnswers>   <comments xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_list />   </comments>   <directSalesAgent xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_dataContract xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" />     <d2p1:_description i:nil="true" />     <d2p1:_hasDataContract>false</d2p1:_hasDataContract>     <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain">       <d3p1:internalValue>6f99f86a-5b1b-4f73-bdc3-388e0b7cf417</d3p1:internalValue>     </d2p1:_id>   </directSalesAgent>   <directSalesAgentSuperVisor xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_dataContract xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" />     <d2p1:_description i:nil="true" />     <d2p1:_hasDataContract>false</d2p1:_hasDataContract>     <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain">       <d3p1:internalValue>d57db20d-9b3a-4345-849e-d5a0d0d88f70</d3p1:internalValue>     </d2p1:_id>   </directSalesAgentSuperVisor>   <photos xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_list>       <d2p1:IdentityDataReferenceOfPhotoDataContractEx>         <d2p1:_dataContract xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" z:Id="i3">           <d2p1:_isDirty>true</d2p1:_isDirty>           <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain">             <d6p1:internalValue>507f45d1-ce3a-4ec2-a343-d0b83cfb7bc8</d6p1:internalValue>           </d2p1:_id>           <d2p1:_key>false</d2p1:_key>           <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier>           <Content i:nil="true" />           <Taken>2013-03-05T17:49:06.294006+02:00</Taken>         </d2p1:_dataContract>         <d2p1:_description i:nil="true" />         <d2p1:_hasDataContract>true</d2p1:_hasDataContract>         <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain">           <d5p1:internalValue>507f45d1-ce3a-4ec2-a343-d0b83cfb7bc8</d5p1:internalValue>         </d2p1:_id>       </d2p1:IdentityDataReferenceOfPhotoDataContractEx>     </d2p1:_list>   </photos>   <salesPoint xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts">     <d2p1:_dataContract xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" />     <d2p1:_description i:nil="true" />     <d2p1:_hasDataContract>false</d2p1:_hasDataContract>     <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain">       <d3p1:internalValue>692a294a-2d1b-4026-9693-0c0ce552a2fb</d3p1:internalValue>     </d2p1:_id>   </salesPoint>   <stockCounts xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts" i:nil="true" /> </VisitDataContractEx> 

Tweaking the XML using Fiddler and testing submissions, I have narrowed down the problem to the element names under _list elements:

.NET:

    <d2p1:_list>       <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU> 

Mono:

    <d2p1:_list>       <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx> 

This is my code which serializes the data:

public string Serialize<TDataContract>(object obj) {     var builder = new StringBuilder();     var serializer = new DataContractSerializer(typeof(TDataContract));     var xmlWriter = XmlWriter.Create(builder);     serializer.WriteObject(xmlWriter, obj);     xmlWriter.Close();      return builder.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", string.Empty); } 

Is this a bug which has to be addressed by the Mono team, or can someone suggest a possible workaround?

Edit:

I've been narrowing this problem down further and it's not about lists, it's about the way each implementation chooses XML element names.

IdentityDataReference takes a generic type, and in this case it's of type CheckListAnswerDataContractEx.

IdentityDataReference also happens to be in a distributed DLL (which I have the source code for), so my suspicion is that DataContractSerializer is using reflection to work out the name automatically, and perhaps as it's a separately distributed DLL, .NET is appending X8I0_S_SPU onto the end, however, Mono is not.

I have also discovered that I can add a name paramater to the DataContractAttribute like so: [DataContract(Name = "IdentityDataReference")] which will override the generated name to just be IdentityDataReference, it doesn't even try adding the Of Type when specified.

Unfortunately a quick test shows Mono is suffering a runtime exception when I specify the name and it tries to deserialize data.

Now that I understand the issue better, I am trying to make an isolated project which replicates the issue.

Edit - Marking as resolved:

I moved on from this project many years ago now, but decided to close this as answered by Katulus since I would feel the same today encountering the same issue. It was our hope at the time we could get "free" painless inter-platform integration with no extra work to an existing WCF service, which turned out to be naive.

Today if presented the same requirement, I would instead choose a more cross platform friendly communication protocol. If I couldn't replace the existing WCF infrastructure, then I would create some sort of facade and/or adapter (possibly in a different solution) which exposes the service over something like WebAPI using JSON serialization, talking to the original WCF service in the background.

like image 846
Jonathan L. Avatar asked Mar 06 '13 08:03

Jonathan L.


People also ask

How to serialize object in WCF?

This code constructs an instance of the DataContractSerializer that can be used only to serialize or deserialize instances of the Person class. DataContractSerializer dcs = new DataContractSerializer(typeof(Person)); // This can now be used to serialize/deserialize Person but not PurchaseOrder.

What is serialization and Deserialization in WCF?

WCF deserializes WCF messages into . Net objects and serializes . Net objects into WCF messages. WCF provides DataContractSerializer by default with a servicecontract. We can change this default serializer to a custom serializer like XMLSerializer.

What is by serialization with respect to WCF?

Windows Communication Foundation (WCF) uses the DataContractSerializer as its default serialization engine to convert data into XML and to convert XML back into data. The DataContractSerializer is designed to serialize data contract types.


1 Answers

If you are communicating between different platforms (even though .NET and Mono try to be the same), you should avoid using DataContractSerializer. There are other possible issues than just this bug. If you for example change classes on the server, all clients may stop working and vice versa. In server-client scenario where you don't have full control of both sides this can be a big issue.

I would change DataContractSerializer to XmlSerializer that you can control better on both sides. Or even implement own serialization to and from XML where you can account with future upgrades. If you add some new property on one server, you can update your deserializer in a way that it can handle if that new property is missing from some old client.

like image 153
Katulus Avatar answered Sep 24 '22 02:09

Katulus