【发布时间】:2013-04-17 20:51:42
【问题描述】:
更新 - 我在这里遇到的问题是用户错误。请参阅下面的答案。
我有一个类,我想添加到 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 一起使用。
而且,我担心必须支持各种绑定。命名管道使用二进制编码,我不确定这会如何影响这个序列化问题——也许这意味着我必须使用代理?
【问题讨论】:
-
从错误消息中 - 你看过Generic Data Contract Resolver吗?
-
我认为 DataContractResolver 会做一些类似于添加 KnownTypeAttributes 的事情,只是它会尝试在一般情况下在运行时这样做。就我而言,我相信 DataContractSerializer 根本无法反序列化类型(例如 JObject),即使它知道它们是什么。
标签: .net wcf json.net datacontractserializer netnamedpipebinding