2012-01-20 5 views
0

私のC#アプリケーションでTCP/IPから受け取ったJSONメッセージをデシリアライズします。ほとんどの場合、1つまたは2つのプロパティを持つ本当に単純なクラスがありますが、それらは導出されています。例:C#JSONデシリアライザは、フォーマットのみをチェックし、オブジェクトデータは気にしません。

public class SemiCommand 
{ 
    public SemiCommand() 
    { 
     UID = string.Empty; 
    } 

    public SemiCommand(string uid) 
    { 
     UID = uid; 
    } 

    public string UID 
    { 
     get; 
     set; 
    } 

    public new string ToString() 
    { 
     return new JavaScriptSerializer().Serialize(this); 
    } 
} 

public class ResponseCommand : SemiCommand 
{ 
    protected const string DEFAULT_INFO = "OK"; 

    public ResponseCommand() 
    { 
     UID = string.Empty; 
     Info = DEFAULT_INFO; 
    } 

    public ResponseCommand(string uid) 
    { 
     UID = uid; 
     Info = DEFAULT_INFO; 
    } 

    public string Response 
    { 
     get; 
     set; 
    } 

    public string Info 
    { 
     get; 
     set; 
    } 


public class GetInfoResponseCommand : ResponseCommand 
{ 
    public GetInfoResponseCommand() 
     : base() 
    { 
     Response = "GetInfoResponse"; 
    } 

    public List<ClientProcess> Processes 
    { 
     get; 
     set; 
    } 
} 

問題を解決するためにDataMember属性とDataContract属性を使用していくつか試行しましたが、修正できませんでした。

は、問題はここにある:

private Type[] _deserializationTypes = new Type[] { typeof(StartProcessesRequestCommand), typeof(RequestCommand) }; 

public RequestCommand TranslateTCPMessageToCommand(string messageInString) 
{ 
    RequestCommand requestCommand = null; 

    for (int i = 0; i < _deserializationTypes.Length; i++) 
    { 
     try 
     { 
      requestCommand = TryDeserialize(_deserializationTypes[i], messageInString); 
      break; 
     } 
     catch 
     { 
     } 
    } 

    if (requestCommand == null || (requestCommand != null && requestCommand.Command == string.Empty)) 
    { 
     throw new System.Runtime.Serialization.SerializationException("Unable to deserialize received message"); 
    } 
    else 
    { 
     return requestCommand; 
    } 
} 

私は必要なすべてのプロパティを含む、適切な形式でデシリアライズしたい場合は、それが動作:

これは動作します。しかし{"Response":"SomeResponse","Info":"Information","UID":"123"}

、これをまた、次のように動作します。{"nonexistingProperty":"value"}

もう1つは、プロパティ値がnullに設定されたRequestCommandを作成します。

第一の質問:私は、1つまたは複数の祖先から派生された複数のコマンドタイプを持っている場合は、どのようにです:どのように私はそれが必要とされる特性の全て

第二の質問を受けた場合にのみ、RequestCommandを作るために私のmessagetranslator機能を強制することができます受け取ったプロパティが許可する場合、自動的に「最も深い」クラスから逆シリアル化することができます。

EDIT:

私はTrySerializeが例外をスローしない場合、ループを終了することになってトライキャッチでブレークこれら2

private RequestCommand TryDeserialize(Type type, string messageInString) 
    { 
     JavaScriptSerializer js = new JavaScriptSerializer(); 
     return (RequestCommand)js.Deserialize(messageInString, type); 
    } 

    public string TranslateCommandToTCPMessage(ResponseCommand command) 
    { 
     JavaScriptSerializer js = new JavaScriptSerializer(); 
     return js.Serialize(command); 
    } 

とデシリアライズ/シリアライズ、したがって、直列化復元に成功しました。

+0

オブジェクトのシリアライズとデシリアライズはどのようにしていますか? TryDeserialize関数の呼び出し後にブレークがある理由 –

+0

はhttp://stackoverflow.com/questions/1100191/javascriptserializer-deserialize-how-to-change-field-namesを見てください。 'TryDeserialize'では' Type'は必要ありません。あなたは 'typeof(RequestCommand)'することができます。また完全なコード、 'RequestCommand'を提供' StartProcessesRequestCommand'、 'ClientProcess'クラスが不足しています。 –

答えて

0

実際にDataContractJsonSerializerを使用し、DataMember/DataContractで問題のメンバー/タイプを修飾した場合は、実際にこの問題が発生する可能性があります。これを行うには、[IsRequired = true]ですべてのデータメンバーを飾ることができます。メンバーがワイヤに存在しない場合、これは例外をスローします。

あなたが持っているもう一つのオプションは、別のポストシリアライズに一つのオブジェクトを翻訳してみましょうIObjectReferenceを、使用することです、そしてあなたは、この線から直列化復元されたものに応じて行うことができます。

関連する問題