没有为Protobuf-net中的类型:System.Management.Automation.PSObject定义的序列化程序

时间:2013-11-06 12:16:44

标签: c# serialization protobuf-net

这是我的班级

  [ProtoContract]
            internal class Powershellresults
            {
                internal Powershellresults()
                {
                }
                [ProtoMember(1)]
                public Collection<PSObject> PsObjects { get; set; }
                [ProtoMember(2)]
                public string Script { get; set; }
                [ProtoMember(3)]
                public string Viewname { get; set; }
            }

但是我得到了没有为类型定义的序列化程序:System.Management.Automation.PSObject 当我尝试序列化时

private byte[] SerializeResults(Powershellresults obj)
        {
            byte[] data;
            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, obj);
                data = ms.ToArray(); ;
            }
            return data;
        }

PsObject是System.Management.Automation

的一部分

我可以绕过这个并实际序列化这个系列吗?

更新: 通过添加到我的序列化方法

RuntimeTypeModel.Default.Add(typeof(PSObject), true);

我可以将它序列化 - 但是一旦序列化它就丢失了大部分字段 我如何让它“克隆”原始对象,以便保留其所有字段和属性?

修改

我明白了! 我心里想,Powershell必须能够序列化它的对象,因为你可以轮询远程机器 - 它如何能够在机器之间发送PSObject - 它确实如此! (哇噢!!!!)

好吧,我发现了一篇描述此内容的文章,并找到了我的关键字System.Management.Automation.PSSerializer

Collection<PSObject> PSCol = Powershell.Invoke(); 
string SerializedCollection = PSSerializer.Serialize(PSCol);

//序列化到XML完成!

然后使用Protobuf-net或其他任何内容串行化字符串......

反序列化有点尴尬但很直接 用于反序列化使用: 使用Protobuf反序列化字符串然后...

PSObject obj = PSSerializer.Deserialize(DeserializedString) as PSObject;

Collection<PSObject> DeserializedCollection = new Collection<PSObject>(((ArrayList)obj.ImmediateBaseObject).Cast<PSObject>().ToArray());

就是这样..

2 个答案:

答案 0 :(得分:4)

我明白了! 我心里想,Powershell必须能够序列化它的对象,因为你可以轮询远程机器 - 它如何能够在机器之间发送PSObject - 它确实如此! (哇噢!!!!)

好吧,我发现了一篇描述此内容的文章,并找到了我的关键字System.Management.Automation.PSSerializer

Collection<PSObject> PSCol = Powershell.Invoke(); 
string SerializedCollection = PSSerializer.Serialize(PSCol);

//序列化到XML完成!

然后使用Protobuf-net或其他任何内容串行化字符串......

反序列化有点尴尬但很直接 用于反序列化使用: 使用Protobuf反序列化字符串然后...

PSObject obj = PSSerializer.Deserialize(DeserializedString) as PSObject;

Collection<PSObject> DeserializedCollection = new Collection<PSObject>(((ArrayList)obj.ImmediateBaseObject).Cast<PSObject>().ToArray());

就是这样..

答案 1 :(得分:1)

PSObject太模糊了,无法成为一个好的序列化候选者(尤其是它是dynamic提供者等);我强烈建议你构建一个定义良好的 DTO模型,即

[ProtoMember(1)]
public Collection<SomeTypeThatYouOwn> Items {get;set;}

其中SomeTypeThatYouOwn具有有意义的属性等。您始终可以转换为/ SomeTypeThatYouOwn接近序列化/反序列化setp。 PSObject基本上是一个属性包,由于protobuf不包含任何元数据(您需要提前知道数据的形状以对其进行有意义的反序列化),因此效果不佳。