更新- ここで発生した問題はユーザー エラーでした。以下の私の答えを見てください。
「バインディングに依存しない」必要がある WCF API の DataContract に追加したいクラスがあります。つまり、BasicHttp や NamedPipe など、複数のバインディングをサポートできる必要があります。データ コントラクトに追加するクラスは、Newtonsoft.Json.Linq.JObject を使用してメンバー データを格納します。
[DataContract]
public class MyFacet
{
public MyFacet(string facetName)
{
Initialize();
FacetName = facetName;
}
internal JObject JsonObject { get; private set; }
[OnDeserializing] // required for deserialization to init JsonObject
private void OnDeserializing(StreamingContext c)
{
Initialize();
}
private void Initialize()
{
JsonObject = new JObject();
}
[DataMember]
public string FacetName
{
get
{
return GetProperty<string>("facet");
}
private set
{
SetProperty("facet", value);
}
}
public string ToJson()
{
return JsonObject.ToString(Newtonsoft.Json.Formatting.None);
}
public T GetProperty<T>(string key)
{
JToken value;
if (JsonObject.TryGetValue(key, out value))
{
return value.Value<T>();
}
return default(T);
}
public void SetProperty(string name, object value)
{
SetProperty(name, new JValue(value));
}
internal void SetProperty(string name, JToken value)
{
JsonObject[name] = value;
}
}
さまざまな理由から、可能な限りこのクラスを維持したいと考えています。(テスト アプリで) DataContractSerializer を使用してこのクラスをシリアル化しようとすると、次のエラーが発生します。
System.Runtime.Serialization.SerializationException:
Type 'ConsoleTest.MyFacet' with data contract name
'MyFacet:http://schemas.datacontract.org/2004/07/ConsoleTest' is not expected.
Consider using a DataContractResolver or add any types not known statically to
the list of known types - for example, by using the KnownTypeAttribute attribute
or by adding them to the list of known types passed to DataContractSerializer.
これは、本質的に、私には理にかなっています。ただし、さまざまな Newtonsoft 型を KnownTypes として追加しても機能しません。これにより、「再帰的なコレクション データ コントラクト」エラーが発生します。DataContractResolver を実装しようとすると、同じ問題が発生すると思います。
Newtonsoft シリアライザーを使用して、JObject を XML にシリアライズできると思います。いくつかのオプションがあるようです:
- IDataContractSurrogate を使用して、JObject のデシリアライズされたサロゲートを提供します
- IClientMessageFormatter を使用してカスタムのシリアル化/逆シリアル化を作成する
- DataContractSerializer の代わりに、または DataContractSerializer と共に Newtonsoft シリアライザーを使用するように、デシリアライゼーションの「システム」を何らかの方法で構成/オーバーライドします。
そして、さまざまなバインディングをサポートしなければならないことが心配です。名前付きパイプはバイナリ エンコーディングを使用していましたが、それがこのシリアライゼーションの問題にどのように影響するかはわかりません。サロゲートを使用する必要があるということでしょうか?