Я сериализую данные в приложении Mono для Android и отправляю его с помощью REST на сервер .NET, использующий WCF. Однако до сих пор это отлично работало с этим конкретным контрактом на данные, хотя сервер не выдает ошибок, списки внутри контракта данных отображаются как пустые.
Используя Fiddler и создав два проекта с одним и тем же кодом, я смог сравнить обычный выход .NET DataContractSerializer с выходом из Mono-реализации DataContractSerializer.
Выход .NET:
<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>
Моновыход:
<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>
Тонкая настройка XML с помощью Fiddler и тестовых представлений, я сузил проблему с именами элементов в _list
:
.NET:
<d2p1:_list>
<d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU>
Mono:
<d2p1:_list>
<d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx>
Это мой код, который сериализует данные:
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);
}
Является ли это ошибкой, которая должна быть решена командой Mono, или кто-то может предложить возможное обходное решение?
Edit:
Я уже сузил эту проблему и не о списках, а о том, как каждая реализация выбирает имена элементов XML.
IdentityDataReference
принимает общий тип, и в этом случае он типа CheckListAnswerDataContractEx
.
IdentityDataReference
также происходит в распределенной DLL (для которой у меня есть исходный код), поэтому я подозреваю, что DataContractSerializer использует рефлексию для автоматического определения имени и, возможно, как отдельно распределенной библиотеки DLL.NET добавляет X8I0_S_SPU
в конец, однако Mono не является.
Я также обнаружил, что я могу добавить имя paramater в DataContractAttribute, например: [DataContract(Name = "IdentityDataReference")]
, который переопределит сгенерированное имя только как IdentityDataReference
, он даже не попытается добавить тип Type, если это указано.
К сожалению, быстрый тест показывает, что Mono испытывает исключение во время выполнения, когда я указываю имя и пытается десериализовать данные.
Теперь, когда я лучше понимаю проблему, я пытаюсь создать изолированный проект, который реплицирует проблему.
Изменить - Пометить как разрешенные:
Я перешел от этого проекта много лет назад, но решил закрыть это, как ответил Катулус, так как я бы чувствовал то же самое, что и сегодня, столкнувшись с той же проблемой. Это была наша надежда в то время, когда мы могли получить "свободную" безболезненную межплатформенную интеграцию без дополнительной работы с существующей службой WCF, которая оказалась наивной.
Сегодня, если у вас есть такое же требование, я бы выбрал более простой межплатформенный протокол связи. Если бы я не мог заменить существующую инфраструктуру WCF, я бы создал какой-то facade и/или adapter (возможно, в другом решении), который предоставляет услугу над чем-то вроде WebAPI с использованием сериализации JSON, разговаривая с исходной службой WCF в фоновом режиме.