Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 序列化异常使用DataContractSerializer序列化newtonsoft jobject_.net_Wcf_Json.net_Datacontractserializer_Netnamedpipebinding - Fatal编程技术网

.net 序列化异常使用DataContractSerializer序列化newtonsoft jobject

.net 序列化异常使用DataContractSerializer序列化newtonsoft jobject,.net,wcf,json.net,datacontractserializer,netnamedpipebinding,.net,Wcf,Json.net,Datacontractserializer,Netnamedpipebinding,更新-我这里的问题是用户错误。见下面我的答案 我有一个类,我想添加到WCF API的DataContract中,它应该是“绑定不可知的”;i、 例如,它应该能够支持多个绑定,包括BasicHttp和NamedPipe。我要添加到数据协定中的类使用Newtonsoft.Json.Linq.JObject存储成员数据: [DataContract] public class MyFacet { public MyFacet(string facetName) { In

更新-我这里的问题是用户错误。见下面我的答案

我有一个类,我想添加到WCF API的DataContract中,它应该是“绑定不可知的”;i、 例如,它应该能够支持多个绑定,包括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;
    }
}
这对我来说基本上是有道理的。但是,将各种Newtonsoft类型添加为KnownTypes不起作用——这会导致“递归收集数据契约”错误。我想如果我尝试实现DataContractResolver,我也会遇到同样的问题

我相信我可以使用Newtonsoft序列化程序将JObject序列化为XML。看来我有几个选择:

  • 使用IDataContractSurrogate并提供作业对象的反序列化代理
  • 使用IClientMessageFormatter创建自定义序列化/反序列化
  • 以其他方式配置/覆盖反序列化“系统”,以使用Newtonsoft序列化程序,而不是DataContractSerializer或与DataContractSerializer一起使用

而且,我担心必须支持各种绑定。命名管道使用二进制编码,我不确定这对序列化问题有何影响——也许这意味着我必须使用代理?

我认为,
KnownType
不会有帮助,因为它应该只帮助“查找”类型,而wcf
DataContractSerializer
应该知道如何进行序列化

它没有,因为
JObject
不包括
DataContract
DataMember
属性


<> > <代码> JObject <代码>是XML可序列化的,我会考虑使用XML序列化而不是DATACONTRORE序列化。

证明这是%100用户错误。在我的序列化测试工具中,我在创建DataContractSerializer时传递了错误的类型。以下内容演示了错误:

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);

一旦我修复了错误,原始post中的类就可以序列化了。我最初收到的错误消息真的让我很反感。我假设是JObject或某个Newtonsoft类型引起了这个问题,但事实上,我甚至没有尝试序列化这些类型中的任何一个。

从错误消息中-您查看过吗?我认为DataContractResolver会做一些类似于添加KnownTypeAttribute的事情,只有它会尝试在一般情况下和运行时这样做。在我的例子中,我相信DataContractSerializer根本无法反序列化类型(例如JObject),即使它知道它们是什么。
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);