2011-09-09 14 views
2

次のクラスを含むアセンブリを参照する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 
    } 

我々は我々のアプリケーションからユーザーオブジェクトを取り込み、サービスでこのメソッドを呼び出すことができます。アプリケーションは、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をシリアライズします。

UPDATE: http://tempuri.org/:CreateUserResult

当社は、当社のサービスに

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

内部例外を介して接続するために、次を使用しています。 InnerExceptionメッセージが '' EndElement ''名前空間 'http://tempuri.org/'からの 'CreateUserResult'は期待されていません。要素 '_someOtherField'を予期しています。 '詳細については、InnerExceptionを参照してください ...次はinnerですnull

+0

バインディングとは何ですか?これはWCFが多数のシリアライザを使用することができ、DataContractSerializerとNetDataContractSerializerのルールが異なるためです。 –

+0

また、非常に重要です:InnerExceptionとは何ですか? (InnerExceptionがnullになるまで) –

+0

サービスにinnnerExceptionとBindingメソッドを追加 – Jay

答えて

2

私が疑うように、ここに問題があります。

NetTcpBinding 

(あなたの編集から)基本的に、WCFにはフレンドリーなコントラクトベースのサポートとあまり使いにくいタイプベースのサポートが含まれています。

可能すべてで場合、私はここで、最も単純なオプションをお勧めしであり、デフォルトでそれとしてNETTCPを使用しないNetDataContractSerializer(タイプベース)を使用するため、は、問題をバージョン管理しているだろう。代わりに、トランスポートでoterシリアライザを使用することもできます。たとえば、protobuf-netのDataContractSerializerです。しかし、これを変えること自体が大きな変化になるでしょう。

NetDataContractSerializerでカスタムバインダーを使用することができます。Problem deserializing with NetDataContractSerializer after refactoring codeを参照してください。それを得ることができるなら、それはAPIを保存するはずですが、過小評価すべきではありません。私はそれがメンテナンスの負担になると思います。私はむしろ損失を減らすために、を一度に破棄し、契約ベースのシリアライザに切り替えます。

関連する問題