2016-05-05 23 views
3

JSON.NETを使用してHTTPクエリからJSON応答を逆シリアル化していますが、問題が残っています。以下に示すように、応答は、同じプロパティの下のオブジェクトの2種類を送ることができるからだ。同じプロパティ名で異なるオブジェクトを持つJSONを逆シリアル化する

第一ケースのサンプル(最も一般的):

{ 
    "type": "myType", 
    "tid": 4, 
    "action": "myAction", 
    "method": "myMethod", 
    "result": { 
    "success": true, 
    "total": 4, 
    "records": [ 
     { 
     "id": 4, 
     "nome": "PRIMEIRO NOME", 
     "sigla": "PN" 
     }, 
     { 
     "id": 1974, 
     "nome": "SEGUNDO NOME", 
     "sigla": "SN" 
     }, 
     { 
     "id": 2584, 
     "nome": "TERCEIRO NOME", 
     "sigla": "TN" 
     }, 
     { 
     "id": 1170, 
     "nome": "QUARTO NOME", 
     "sigla": "QN" 
     } 
    ] 
    } 
} 

第二ケースのサンプル(まれ):

{ 
    "type": "myType", 
    "tid": 3, 
    "action": "myAction", 
    "method": "myMethod", 
    "result": [ 
    { 
     "id": 4, 
     "nome": "PRIMEIRO NOME", 
     "sigla": "PN" 
    }, 
    { 
     "id": 1974, 
     "nome": "SEGUNDO NOME", 
     "sigla": "SN" 
    }, 
    { 
     "id": 2584, 
     "nome": "TERCEIRO NOME", 
     "sigla": "TN" 
    }, 
    { 
     "id": 1170, 
     "nome": "QUARTO NOME", 
     "sigla": "QN" 
    } 
    ] 
} 
私は第一ケースのためのデータを受信するために、これらのクラスを使用してきた

Public Class Record 
    Public Property id As Integer 
    Public Property nome As String 
    Public Property sigla As String 
End Class 

Public Class Result 
    Public Property success As Boolean 
    Public Property total As Integer 
    Public Property records As Record() 
End Class 

Public Class Response 
    Public Property type As String 
    Public Property tid As Integer 
    Public Property action As String 
    Public Property method As String 
    Public Property result As Result 
End Class 

だからそれは時にうまく働きましたこの文を使用して第一ケースJSONの直列化復元、:第二ケースJSONを受信したときに

Dim myResponse = JsonConvert.DeserializeObject(Of Response)(myJsonString) 

しかし、それはその性質結果タイプ結果のオブジェクトプロパティでタイプレスポンス、店舗のオブジェクトを作成します空のままにしておき、私が検索する必要があったデータはどこにも保存されません。

私はそれがデータの異なるセット、この方法のための場所を持っているので、私はクラスの応答を変更する必要があることを考え

Public Class Response 
    Public Property type As String 
    Public Property tid As Integer 
    Public Property action As String 
    Public Property method As String 
    Public Property result As Result 
    Public Property resultRecords As Record() 
End Class 

質問、そして、これです:どのように私はJsonConvertを伝えることができます保存するかどうかプロパティのデータResponse.resultのタイプ(上記の1番目のサンプルの場合)またはResponse.resultRecords 2番目のケースでは?

ありがとうございました!

+0

'tid'はタイプを示していますか?意味は、最初のものはすべて「4」で、2番目のものはすべて「3」ですか? – Plutonix

+0

は残念ながらありません、@Plutonixは、 'tid'は、「トランザクションID」ということであるインデックスとペアPOSTDATAもJSONであると増分TID値を送信する必要があります彼らの元の要求と応答を。しかし、助けてくれてありがとう! – VBobCat

答えて

3

JSONの書式は同じプロパティで異なる可能性がありますので、それを処理するにはカスタムJsonConverterが必要です。コンバーターは影響を受けたプロパティのJSONを読み込み、その形式を決定してオブジェクトを適切に埋め込むことができます。

Public Class ResultConverter 
    Inherits JsonConverter 

    Public Overrides Function CanConvert(objectType As Type) As Boolean 
     Return objectType = GetType(Result) 
    End Function 

    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object 
     Dim token As JToken = JToken.Load(reader) 
     Dim result As Result = New Result 
     If token.Type = JTokenType.Array Then 
      result.records = token.ToObject(Of Record())(serializer) 
      result.total = result.records.Length 
      result.success = True 
     Else 
      serializer.Populate(token.CreateReader(), result) 
     End If 
     Return result 
    End Function 

    Public Overrides ReadOnly Property CanWrite As Boolean 
     Get 
      Return False 
     End Get 
    End Property 

    Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer) 
     Throw New NotImplementedException 
    End Sub 
End Class 

をコンバータを使用するには、あなたのResponseクラスのresultプロパティに<JsonConverter>属性を追加します:ここではあなたが必要となるコードがある。ここ

Public Class Response 
    Public Property type As String 
    Public Property tid As Integer 
    Public Property action As String 
    Public Property method As String 
    <JsonConverter(GetType(ResultConverter))> 
    Public Property result As Result 
End Class 

は、このコンバータを示すための作業フィドルです両方のJSONフォーマットを同じクラスにデシリアライズすることができます:https://dotnetfiddle.net/NFbQ2Q

+0

あなたは男です!それは魅力のように働いた。加えて、私のクラス構造が複雑になるという問題を解決しました。それはほとんど見えないかもしれませんが、私は読者のために、私が投稿したサンプルを深く剪定しました。私の最初のアイデアは、プログラムの他の部分に2つの異なる場所でレコードを探すことを要求するでしょう。あなたのソリューションは、珍しいスキームをちょうど収めました。ありがとう! – VBobCat

+0

問題ありません。私は助けてくれてうれしいです。 –

関連する問題