1

我更新了现有的 WCF 应用程序以添加 protobuf-net 支持。基本上,我有:

  • 在包含我所有数据对象的程序集中添加了 protobuf-net.dll (.net 3.0) 作为引用。我的服务器和客户端都引用了这个程序集

  • 将 [DataMember] 替换为 [DataMember(Order = x)] (使用递增的整数作为 x)

  • 使用 ProtoBehavior 属性更新了我的所有 OperationContracts

  • 更新了我的服务参考

从客户端,我在服务器上调用此方法:

[OperationContract(IsOneWay = false), ProtoBehavior]
ConnectionData Join(string userId, string Password);

ConnectionData 的定义如下:

[DataContract]
public class ConnectionData
{
    [DataMember(Order = 1)]
    public ConnectionStatusEnum ConnectionStatus; // this is a normal enum with five elements

    // .....

    [DataMember(Order = 5)]
    public bool MustChangePassword;
}

现在,这是发生了什么:

  • 如果我调试服务器,我会看到 ConnectionData 对象已正确初始化并在 Join 方法中返回

  • 如果我调试客户端,我会看到我的 Join 调用返回了一个空对象

  • 我已将 WCF 跟踪启用到最大详细程度,在服务器日志中没有引起我的注意,但在客户端日志文件中我看到了以下警告消息:

System.Runtime.Serialization.ElementIgnored
在反序列化期间在 XML 中遇到无法识别的元素,该元素被忽略。
元素 http://tempuri.org/:proto

我已经嗅探了我的网络流量,我不怪 protobuf-net 无法反序列化:

<s:Body><JoinResponse xmlns="http://tempuri.org/"><proto/></JoinResponse></s:Body>

如何进一步解决问题并让 protobuf-net 正确序列化我的消息?


我正在使用 protobuf-net r275

4

2 回答 2

0

抱歉耽搁了——工作时间等。两端都知道这个变化吗?不幸的是,WCF 集成不能很好地与客户端上的“mex”生成的代理一起使用,但可以与程序集共享一起使用。

或者,有一些工作正在进行中,以使用可以在配置中指定的端点行为;这不是 100%,但应该很快 - 并允许 WCF 透明地使用 protobuf-net,无需修改服务合同(尽管成员仍然需要通过[ProtoMember(n)]etc 或[DataMember(Order=n)].

于 2009-10-23T15:39:05.760 回答
0

我在这方面做了更多的工作,我怀疑问题是你有一个服务引用(通过 IDE 或通过 svcutil),即使它重用了共享数据合同,也会导致合同接口被复制(并丢失行为属性,使其损坏)。

选项:

  • 不要使用服务引用(直接使用通道或子类ClientBase<T>
  • 使用新的端点配置选项
  • 破解生成的界面以包含行为(产生维护问题)

如果您不熟悉它们,我计划在接下来的几天内为第一个选项写一篇博客文章。

于 2009-11-11T17:43:53.977 回答