11

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>

など、属性でクラスをカバーする必要はありませんか?

これの出力が毎回正しいことが保証される方法がない場合はどうなりますか?これを使用してオブジェクトグラフをレンダリングすると、ファイル生成用のX *ドキュメントとマッシュアップするXMLになり、ノードの名前が変更されてドキュメントが空白で正しく表示されるという問題が発生することはありませんか?

4

4 に答える 4

9

AgentNotificationこれは、タイプ(たとえば)に。でマークを付けている必要があるために発生しています[Serializable]。でマークされているが明示的ではないタイプにDataContractSerializer遭遇すると、クラスのシリアル化方法に一致するタイプのデフォルトコントラクトが生成されます。これは、クラスのすべてのメンバー変数(プライベートとしてマークされている変数も含む)を名前でシリアル化することです。自動実装されたプロパティの場合、これはシークレットバッキングフィールドが名前でシリアル化されることを意味します。それらの名前は、あなたが見ている独特の要素名です。[Serializable][DataContract]BinaryFormatter

これを解決する最も簡単な方法は[Serializable]、クラスから属性を削除することです。BinaryFormatter実際にまたはを使用していない限り、ほぼ確実にそれは必要ありませんSoapFormatter。そうすると、DataContractSerializerパブリックフィールドとプライベートフィールドを名前でシリアル化するのではなく、パブリックプロパティとフィールドを名前でシリアル化するようになります。

于 2015-07-19T07:28:59.513 に答える
5

長い要素名(_x003C_Created_x003E_k__BackingFieldなど)は、autopropertiesを使用するときに.NETによって作成されます。

それらをバッキングフィールドのあるプロパティに変更した場合、代わりにバッキングフィールド名が使用されます。コードに属性を追加せずにそれを行うことができます。

(それ以上に、クラス定義に[DataContract]属性を追加するだけで、XMLが大幅に整理されますが、完全ではありません。)

于 2010-02-23T03:52:48.880 に答える
1

DataContractSerializer、すべてのパブリックプロパティ(何も指定しない場合-.NET 3.5 SP1以降で可能)、または(私が好むアプローチ)[DataMember]属性でラベル付けしたものをシリアル化します。

したがって、できる最善の方法は、クラスに[DataContract]属性をマークし、データコントラクトに本当に必要なすべてのメンバー(プロパティ、フィールドなど)に属性をマークすること[DataMember]です。

DataContractSerializerは、実際にはそれ以上の制御を許可していません。シリアル化されるものを(この明示的な「オプトイン」アプローチを使用して)非常に明確に定義できますが、シリアル化される方法をほとんどまたはまったく制御できません。

しかし、本当にそれが必要ですか?本当?

その場合、代わりにそのシリアル化プロセスにXmlSerializerを使用する必要があります-そこで、シリアル化の方法をより細かく制御できますただし、欠点として、XmlSerializerは、属性で明示的にマークされていないすべてのパブリックプロパティをシリアル化し[XmlIgnore]ます- 「オプトアウト」スキーム)。

DataContractSerializerとXmlSerializerの違いと、それぞれが提供するものについてのDanRigsbyのブログ投稿を確認してください。

于 2009-12-23T17:04:38.817 に答える
0

ついに同じ問題に遭遇したので、モデルに[DataContract]和[DataMember]を追加するだけです。

于 2015-03-25T08:49:44.507 に答える