【问题标题】:Serialization issue with protobuf and WCFprotobuf 和 WCF 的序列化问题
【发布时间】:2018-01-19 05:40:33
【问题描述】:

我正在使用 protobuf 序列化数据集并将其从 WCF 服务发送到 winfom 客户端。

我在这里面临两个问题...

  1. DataSet 来自 DB,它包含一个 system.Object 类型的列,protobuf 无法处理并抛出异常...

    无法序列化“System.Object”类型的数据列。仅支持以下列类型:Boolean、Byte、Byte[]、Char、Char[]、DateTime、Decimal、Double、Guid、Int16、Int32、Int64、Single、String。"}

数据集序列化代码

using (var ms = new MemoryStream())
                    {
                        if (ReportData.Tables.Count > 0)
                        {
                            DataSerializer.Serialize(ms, ReportData);
                           }
                    }

如何强制 protobuf 序列化 system.Object 数据类型列。 我尝试将此 system.Object 类型列转换为字符串然后序列化...在这种情况下一切正常,但这是一个耗时的过程,因为我需要克隆表并导入所有行(我的数据集包含数百万行)。

 DataTable dtCloned = ReportData.Tables[0].Clone();
                    foreach (DataColumn column in dtCloned.Columns)
                    {
                        if (column.DataType == typeof(System.Object))
                            objectColumns.Add(column);
                    }
                    if (objectColumns.Count > 0)
                    {
                        foreach (DataColumn column in objectColumns)
                        {
                            column.DataType = typeof(System.String);
                        }
                    }
                    try
                    {
                        foreach (DataRow row in ReportData.Tables[0].Rows)
                        {
                            dtCloned.ImportRow(row);
                        }
                    }
                    catch (Exception ex)
                    {

                    }

这是我为此编写的示例代码。 此 System.Object 的 DB 类型是 SQL_Variant,我们无法更改它,因为这是旧版 SP,并且该列包含不同类型的数据(十进制、int varchar)。

有没有更好的方法来达到同样的效果。

  1. 当这个序列化失败并抛出错误时......在客户端我收到了通信异常,它不知道出了什么问题。它唯一说的是......

    “在可靠会话完全完成之前,底层安全会话出现故障。可靠会话出现故障。”

我尝试在 WCF 服务端设置下面的东西,但没有用...

 <serviceDebug includeExceptionDetailInFaults="true" />

也尝试通过 FaultException... 没有运气

如何将正确的异常和信息从 WCF 服务传递给我的客户端。

提前致谢。

【问题讨论】:

  • 我可以检查一下:这里的 DataSerializer 是什么? Protobuf-net 从未在核心库中附带 DataTable 序列化,所以:那到底是什么?那是演示自定义序列化代码吗?
  • 我们使用的是 Assembly: protobuf-net-data, Version=2.0.6.640, Culture=neutral, PublicKeyToken=3a92fdc8f425ccde。它附带 protobuf。
  • “它带有 protobuf”——不,它没有。我是protobuf-net的作者; protobuf-net-data 是一个完全独立的工具,由另一个使用 protobuf-net 的开发人员开发,但与protobuf-net 没有从属关系或关联。比较“所有者”字段 herehere
  • 是的... protobuf-net-data 是单独的 dll... 支持 DataSet/DataTable 序列化。 protoBuf 有没有办法序列化包含 System.Object 类型的 dataTable
  • 不是真的;我在回答和对回答的评论中对此进行了扩展;它只是不太喜欢object(有充分的理由)。它可以是强制的,但是 a:我不推荐它,并且 b:我怀疑你是否能够将它与通过这个其他库添加的 DataTable 支持结合起来

标签: c# wcf serialization protobuf-net communicationexception


【解决方案1】:

最终,protobuf-net 对object 提出了一些相当基本的反对意见。它也不附带对DataTable 的预构建支持。坦率地说,我会挑战使用 DataTable 作为交换类型的适用性,更喜欢类型良好的 DTO。

如果您出于某种原因必须使用DataTable,我想知道您是否最好单独序列化,确保使用二进制格式(参见RemotingFormat)并写入MemoryStream,然后取出字节(在这种情况下为ToArray),只需将byte[] 交给WCF。在另一端反转。

【讨论】:

  • 是的...我尝试使用二进制序列化程序单独序列化 DataTable 并且效果很好。想用 Protobuf 检查是否可以处理对象数据。另外...将正确的异常消息传递给客户端...任何建议...
  • @Abhash786 如果你使用BinaryFormatter:确保在数据表上设置RemotingFormat。至于异常消息:不知道。在 protobuf-net / object 上:is 通过“动态类型”提供一些基本支持(与 dynamic 关键字无关 - 只是:将一些类型元数据刻录到对象中),但它是一种效率不高且易碎的粗略黑客攻击。我想支持已添加到 google 库中的“Any”功能,但我还没有找到时间研究它。这效率低下,但至少符合新规范:)
  • 您好,我有同样的要求,我使用 WCF 使用来自旧系统的数据集,并且需要将服务移动到仍然使用数据集的 gRPC,您找到方法了吗?欣赏它
  • @VAAA 你在使用 protobuf-net.Grpc 吗?我很乐意向您展示如何将编组器换成特定类型,因此您可以使用此答案中的相同方法
  • 非常感谢@MarcGravell 我真的很感激,因为这让我从 1 周开始就头疼。你怎么给我看?非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多