【问题标题】:No serializer defined for type: System.Management.Automation.PSObject in Protobuf-net没有为类型定义序列化程序:Protobuf-net 中的 System.Management.Automation.PSObject
【发布时间】:2013-11-17 16:20:05
【问题描述】:

这是我的课

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

就是这样。

【问题讨论】:

  • publics 替换internals 是否有效?

标签: c# serialization protobuf-net


【解决方案1】:

PSObject 太模糊了,不能成为一个好的序列化候选者(尤其是dynamic 提供者等);我强烈建议您构建一个定义明确的 DTO 模型,即

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

其中SomeTypeThatYouOwn 具有有意义的属性等。您始终可以在序列化/反序列化设置附近转换为SomeTypeThatYouOwn 或从SomeTypeThatYouOwn 转换。 PSObject 基本上是一个属性包,它不能很好地工作,因为 protobuf 不包含任何元数据(您需要提前知道数据的形状才能有意义地对其进行反序列化)。

【讨论】:

  • 太糟糕了,我有很多脚本(由最终用户创建),我需要通过套接字序列化返回数据。你知道有其他方法吗
  • @AlekCarlsen 恐怕我没有魔杖可以挥动。 有些事情可能会完成,但从根本上说,PSObject 有点发明了自己的动态类型系统,与常规 CLI 类型系统相去甚远。
  • 我想通了 - 阅读有关 System.Management.Automation 的文档 - 但无论如何感谢 - 很棒的图书馆 btw (y)
【解决方案2】:

我想通了! 我心想,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());

就是这样。。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多