【问题标题】:Binary deserialize a vb.net class in different .net project二进制反序列化不同.net项目中的vb.net类
【发布时间】:2017-04-27 23:05:42
【问题描述】:

我正在通过套接字连接(如果您想知道是远程桌面通道)从 32 位 .net 程序发送一些数据。我必须发送一些二进制数据(实际上是一些基本的电子邮件信息 + Outlook 的文件附件)。电子邮件 + 主题是“文本”数据,但文件当然可以/将是二进制的。

所以我有一个这样的结构(或类):

<Serializable>
Public Class oEmail
   ' we serialize this into one Byte() object - send to client and then deserlize
 Public Email As String         ' outlook email
 Public Subject As String       ' outlook subject
 Public CC As String            ' outlook CC
 Public BC As String            ' outlook bc (blind copy)
 Public MessageText As String   ' message text
 Public AttachPath As String    ' path name to attachment (with \)
 Public AttachFileName As String
 Public FileDat As New Byte()    ' any kind of windows file - to be attached to outlook
End Class

现在,二进制序列化“将”成为猫的叫声。我可以采用上面的结构——将它序列化为一个字节数组,然后简单地将其通过网络管道发送到客户端,然后将其放入软木塞中。

例如:

Dim MyOutlook As New oEmail
MyOutlook = Deserialize(Of oEmail)(MyData)

反序列化代码真的很简单:

Public Shared Function Deserialize(Of T)(ByVal data As Byte()) As T
        Dim binFormat = New BinaryFormatter()

        Using M As New IO.MemoryStream(data, False)
            Return CType((New BinaryFormatter).Deserialize(M), T)
        End Using

End Function

但是,在客户端,它是一个 64 位应用程序。它也是 .net,但由 RDP 客户端作为外部非托管 .dll 调用,而后者又运行托管代码。长话短说,我无法在客户端软件端为上述类结构添加或使用 SAME .dll。

所以,当我尝试在客户端反序列化时,我当然会收到这条 BEYOND 讨厌的消息:

无法找到程序集“RDPSERVER”;版本 1.0.0.0

.net 不允许对一个类进行二进制序列化,除非您使用完全相同的 .dll 和程序集,这“非常”令人遗憾。 (为什么没有提供一些“松散”的序列化方法超出了我的理解——但我不想在这里咆哮!)。我的意思是,获取 byte() 数据 - 将其映射回类或结构!

有没有办法“覆盖”EXACT 装配要求和不匹配问题?

当一个人可以共享 .dll 时,如此简单。但是,我可以在两个应用程序(客户端和服务器)之间共享源代码。

当然上面给出了程序集不匹配。

我愿意考虑使用 XML 序列化程序(但它会完整地传输文件等二进制数据吗?)。而且 XML 序列化也不会创建 byte() 数组。

有没有办法用二进制序列化覆盖 .net 要求的“精确组装”要求?

代码是 vb.net,但如果一段简单的 c# 代码允许覆盖程序集名称,我愿意接受 c# 代码。

【问题讨论】:

  • 您是否考虑过使用程序集别名? msdn.microsoft.com/en-us/library/ms173212.aspx
  • ProtoBuf-NET 救援(由 SO 员工撰写,所以你知道它的好处)
  • 序列化成JSON或者其他文本格式怎么样,如果需要更小可以gzip压缩。
  • 如果您不想添加任何库,请使用 XmlSerializer,它包含在 .net 框架中,可以避免这些错误类型。 BinaryFormatter 有点让人头疼。是的,它会传输任何二进制数据,它会更大,但会起作用。
  • 另外,如果您只想序列化该类并获得最佳性能,为什么不手动序列化/反序列化呢?如果你愿意,我可以添加一个关于如何做的例子。

标签: c# .net vb.net serialization


【解决方案1】:

因为程序集不匹配(并且希望避免使用外部 dll)。我会使用 XML serlization。以下两个例程确实有效,但将发送的 byte() 数据的大小增加了 3 倍

   Public Shared Function SerializeXML(ByVal data As Object) As Byte()
        Dim ser As XmlSerializer = New XmlSerializer(data.GetType)
        Dim xBuff As New StringWriter

        ser.Serialize(xBuff, data)

        Return System.Text.Encoding.Unicode.GetBytes(xBuff.ToString)
    End Function


    Public Shared Function DeSerializeXML(Of T)(ByVal data As Byte()) As T
        Dim ser As New XmlSerializer(GetType(T))
        Dim XbUF As New MemoryStream
        XbUF.Write(data, 0, data.Length)
        XbUF.Position = 0
        Return ser.Deserialize(XbUF)
    End Function

因此,一旦将 data() 缓冲区发送到 RDP 通道,我就使用它:

       Dim MyEmailLoc As New oEmail

        MyEmailLoc = DeSerializeXML(Of oEmail)(MyData)

因此,上述内容使我能够将类对象发送到网络管道,但开销很大。

【讨论】:

    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2011-06-08
    相关资源
    最近更新 更多