Есть ли способ сделать DataContractSerializer более чистым XML?
Используя DataContractSerializer для сериализации моего объекта, я получаю вывод, похожий на
<?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>
Есть ли способ для вывода тегов, которые просто
<Id>
<Name>
и т.д., без необходимости покрывать мои классы атрибутами?
Если нет способа, то результат этого гарантируется, что каждый раз будет правильным? Таким образом, если я использую это для визуализации моих графиков объектов, то XML файл должен скомпоноваться с документом X * для генерации файлов, что я никогда не столкнусь с проблемой, когда мои узлы меняют имена, а документ получается пустым правильно?
Ответы
Ответ 1
Это происходит потому, что вы должны отмечать ваши типы (например, AgentNotification
) [Serializable]
. Когда DataContractSerializer
встречается с типом, отмеченным [Serializable]
, но без явного [DataContract]
, он генерирует контракт по умолчанию для типа, который соответствует тому, как BinaryFormatter
сериализует класс, который предназначен для сериализации все переменные-члены класса - четные переменные, помеченные как частные - по имени. Для автоматически реализованных свойств, это означает, что секретные поля поддержки становятся сериализованными по имени; их имена - это уникальные имена элементов, которые вы видите.
Самый простой способ решить это - удалить атрибут [Serializable]
из ваших классов. Вы почти наверняка не нуждаетесь в этом, если вы на самом деле не используете BinaryFormatter
или SoapFormatter
. Сделав это, DataContractSerializer
теперь будет сериализовать ваши общедоступные свойства и поля по имени, а не публичные и частные поля по имени.
Ответ 2
Длинные имена элементов (например, _x003C_Created_x003E_k__BackingField) создаются .NET при использовании автопрограмм.
Если вы изменили их на свойства с полями поддержки, вместо этого они будут использовать ваши имена полей поддержки. Вы можете сделать это без добавления каких-либо атрибутов в свой код.
(Помимо этого, просто добавив атрибут [DataContract] к определению вашего класса, вы будете много убирать свой XML-код, хотя и не полностью.)
Ответ 3
DataContractSerializer
будет сериализовать либо все общедоступные свойства (если вы не укажете ничего - возможно, как .NET 3.5 SP1) или (подход, который я предпочитаю), все, что вы наклейте с помощью атрибута [DataMember].
Поэтому лучше всего пометить ваш класс атрибутом [DataContract]
, и все члены (свойства, поля и т.д.), которые вы действительно хотите в ваших данных, с атрибутом [DataMember]
.
DataContractSerializer на самом деле не позволяет намного больше контролировать, чем это: вы можете четко определить (используя этот явный подход "входить" ) , что получает сериализованность, но у вас мало или вообще нет контроля над , как он сериализуется.
Но вам это действительно нужно? На самом деле?
Если это так, вам, скорее всего, придется использовать XmlSerializer для этого процесса сериализации - там вы можете получить больше контроля над тем, как вещи сериализуются (но в качестве недостатка XmlSerializer будет сериализовывать каждый общедоступное свойство, которое явно не отмечено атрибутом [XmlIgnore]
- схемой "отказа" ).
Отъезд Dan Rigsby сообщение в блоге о различиях между DataContractSerializer и XmlSerializer и о том, что каждый из них может предложить.
Ответ 4
Я встретил такую же проблему, наконец, вам просто нужно добавить [DataContract] 和 [DataMember] к модели.