Update -这里的问题是用户错误。请看下面我的回答。
我有一个类,我想添加到一个WCF API的数据合约,它应该是"绑定不可知论";也就是说,它应该能够支持多种绑定,包括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序列化器将jobobject序列化为XML。似乎我有几个选项:
- 使用idatacontractproxy并提供一个反序列化的jobobject代理
- 使用IClientMessageFormatter创建自定义序列化/反序列化
- 以其他方式配置/覆盖反/序列化'系统'以使用Newtonsoft序列化器而不是DataContractSerializer。
而且,我担心必须支持各种绑定。命名管道使用二进制编码,我不确定这对序列化问题有何影响——也许这意味着I 必须使用代理?
我认为,KnownType
将不会有帮助-因为它应该只帮助"找到"类型,当wcf DataContractSerializer
应该知道如何序列化。
不存在,因为JObject
不包含DataContract
和DataMember
属性。
如果JObject
是可xml序列化的,我会考虑使用xml序列化而不是DataContract序列化。
原来是%100用户错误。在我的序列化测试工具中,我在创建DataContractSerializer时传递了错误的类型。下面演示了ERROR:
Console.WriteLine("serializing...");
MyFacet facet = new MyFacet("MyFacet");
// On the following line, I was passing the wrong type to the ctor.
// Needed to pass "MyFacet" here, not "Person"
//!ERROR
DataContractSerializer serializer = new DataContractSerializer(typeof(Person));//!ERROR
var settings = new XmlWriterSettings { Indent = true };
using (var writer = XmlWriter.Create(fileName, settings))
serializer.WriteObject(writer, facet);
一旦我修复了这个错误,原始帖子中的类就可以序列化了。我最初收到的错误信息真的把我弄糊涂了。我假设是JObject或Newtonsoft类型引起了这个问题,而事实上,我甚至没有试图序列化这些类型中的任何一个。