更新- 我在这里遇到的问题是用户错误。请看下面我的回答。
我有一个要添加到 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 创建自定义序列化/反序列化
- 以其他方式配置/覆盖反序列化“系统”以使用 Newtonsoft 序列化程序代替 DataContractSerializer 或与 DataContractSerializer 一起使用。
而且,我担心必须支持各种绑定。命名管道使用二进制编码,我不确定这会如何影响这个序列化问题——也许这意味着我必须使用代理?