c# - 具有不同引用版本的客户端和服务器之间的序列化

标签 c# wcf serialization deserialization

我有一个 Windows 服务引用了一个包含以下类的程序集。

 [Serializable]
 public class User
    {
        public User(string userName)
        {
            UserName = userName;
        }

        public string UserName { get; private set; }
    }

这个服务有一个方法允许我们创建一个用户:

public User CreateUser(User user)
        {
        //Create and return user
    }

通过远程处理,我们能够在从我们的应用程序接收用户对象的服务中调用此方法。应用程序引用与服务为用户类所做的相同的程序集,但它强制使用特定的 1.0.0.0 版本。

CreateUser(User user);

我们想更改从每个项目引用的现有程序集,以将新属性“Phone”添加到 User 类。

 [Serializable]
 public class User
    {
        public User(string userName)
        {
            UserName = userName;
        }

        public string UserName { get; private set; }
        **public string Phone { get; set; }**
    }

我们会将程序集版本从 1.0.0.0 增加到 2.0.0.0。 Windows 服务将引用 GAC 中程序集的 2.0.0.0 版本。因为我们的一些客户升级速度很慢,他们强制使用特定版本的程序集或将其复制到本地,他们仍将引用 1.0.0.0 版本。

随着对服务程序集引用的更改,将对象从服务反序列化/序列化到应用程序的编码器抛出序列化错误。 “格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数时出错...”

我们所做的更改应该是非破坏性更改,因为我们刚刚添加了附加功能。有没有办法允许现有应用程序继续使用 1.0.0.0 版本的程序集,并在没有新属性的情况下序列化 2.0.0.0 到它们,而不需要对服务进行一些复杂的转换?

更新:

我们正在使用以下连接到我们的服务

marshaller = ChannelFactory<T>.CreateChannel(new NetTcpBinding() { MaxReceivedMessageSize = MaxResponseSize }, new EndpointAddress(new Uri(new Uri(servers[serverIndex]), serviceName)));

内部异常: http://tempuri.org/:CreateUserResult . InnerException 消息是来自命名空间“http://tempuri.org/”的“EndElement”“CreateUserResult”不是预期的。期待元素“_someOtherField”。有关更多详细信息,请参阅 InnerException ...下一个内部为空

最佳答案

正如我所怀疑的,这是问题所在;

NetTcpBinding

(来自您的编辑)。基本上,WCF 包括一些非常友好的基于契约的支持,以及一些不太友好的基于类型的支持。

如果完全可能,我建议这里最简单的选择是不使用 NetTcp,因为它默认使用 NetDataContractSerializer(基于类型),所以 有版本控制问题。或者,您可以在传输上使用其他序列化程序 - 例如 protobuf-net 的 DataContractSerializer。但是,更改此设置本身就是一项重大更改。

我了解到可以将自定义绑定(bind)器与 NetDataContractSerializer 一起使用 - 请参阅 Problem deserializing with NetDataContractSerializer after refactoring code .如果你能让它工作,它应该保留 API,但它不应该被低估;老实说,我认为这将是一个维护负担。我宁愿减少损失,破坏 API 一次并切换到基于契约的序列化程序。

关于c# - 具有不同引用版本的客户端和服务器之间的序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7365190/

相关文章:

wcf - 如何在配置文件中创建没有设置的 WCF 客户端?

json - 多个json字符串的分隔符

c# - 为什么我的无效 WCF 消息没有被记录?

c# - 在一定数量的字符和换行符之后分割字符串。在 C# 中

c# - 如何在 UWP/UAP 上实现模板

c# - 列表是按值传递的吗?

wcf - 可以在WCF中合并通话吗?

c# - 如何将 WCF 样式格式的日期字符串(即 "/Date(1342210377000)/")转换为 c# DateTime?

c++ - 当对字段使用不同的值时,Protobuf 序列化长度不同

c# - SelectMany 时最小起订量验证失败