Есть ли способ сделать вывод DataContractSerializer более чистым XML? - PullRequest
11 голосов
/ 23 декабря 2009

Используя 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>some@email.com</_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 * для генерации файлов, и я никогда не столкнусь с проблемой, когда мои узлы меняют имена и документ выходит пустым правильно?

Ответы [ 4 ]

9 голосов
/ 19 июля 2015

Это происходит потому, что вы должны пометить свои типы (например, AgentNotification) как [Serializable]. Когда DataContractSerializer встречает тип, отмеченный [Serializable], но без явного [DataContract], он генерирует контракт по умолчанию для типа, который соответствует как BinaryFormatter сериализует класс, который должен сериализовать все переменные-члены класса - даже переменные, помеченные как частные - по имени. Для автоматически реализуемых свойств это означает, что секретные резервные поля будут сериализованы по имени; их имена - это особые имена элементов, которые вы видите.

Самый простой способ решить эту проблему - удалить атрибут [Serializable] из ваших классов. Вам почти наверняка это не нужно, если вы на самом деле не используете BinaryFormatter или SoapFormatter. Сделав это, DataContractSerializer теперь будет сериализовать ваши публичные свойства и поля по имени, а не публичные и приватные поля по имени.

5 голосов
/ 23 февраля 2010

Длинные имена элементов (например, _x003C_Created_x003E_k__BackingField) создаются .NET при использовании автообъектов.

Если вы измените их на свойства с полями поддержки, они вместо этого будут использовать ваши имена полей поддержки. Вы можете сделать это без добавления каких-либо атрибутов в ваш код.

(Кроме того, простое добавление атрибута [DataContract] к определению вашего класса приведет в порядок ваш XML, хотя и не полностью.)

1 голос
/ 23 декабря 2009

DataContractSerializer будет сериализовать либо все общедоступные свойства (если вы ничего не указываете - возможно, начиная с .NET 3.5 SP1), либо (что я предпочитаю) все, что вы пометите атрибутом [DataMember].

Поэтому лучшее, что вы можете сделать, - пометить свой класс атрибутом [DataContract], а все члены (свойства, поля и т. Д.), Которые вы действительно хотите в своем контракте данных, - атрибутом [DataMember].

DataContractSerializer на самом деле не позволяет намного больше контроля, чем это - вы можете довольно четко определить (используя этот явный подход "opt-in") что сериализуется, но у вас мало или нет контроля над как сериализуется.

Но тебе это действительно нужно? На самом деле?

Если это так, вам, вероятно, придется вместо этого использовать XmlSerializer для этого процесса сериализации - там вы можете получить больший контроль над тем, как вещи сериализуются (но в качестве недостатка XmlSerializer будет сериализовать каждую публичную версию). свойство, которое явно не помечено атрибутом [XmlIgnore] - схема отказа)

Ознакомьтесь с блогом Дэна Ригсби о различиях между DataContractSerializer и XmlSerializer и о том, что каждый из них может предложить.

0 голосов
/ 25 марта 2015

Я столкнулся с той же проблемой, наконец, поэтому вам просто нужно добавить [DataContract] 和 [DataMember] к модели.

...