0

RestSharp が特定の JSON 結果を逆シリアル化できるように、POCO クラスを構築しようとしています。問題は、ルート オブジェクトに nb_results キーと他のキーの辞書 ("0:"、"1:" など、それぞれが複雑な値を持つ) の両方が含まれていることです。

Dictionary(Of Integer, mediaGalleryData) と Dictionary(Of String, mediaGalleryData) の両方を試しました。どちらも機能しません。nb_results は常にシリアライズしますが、ディクショナリは決してシリアライズしません。

{
  "nb_results": 2,
  "0": {
    "id": 51976254,
    "title": "Bumblebee species Bombus terrestris",
    "media_type_id": 1,
    "creator_name": "paulrommer",
    "creator_id": 201446851,
    "thumbnail_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/51\/97\/62\/110_F_51976254_dVCbgGVey5xEuLkvk1e4vhnmPqxI4J0X.jpg",
    "thumbnail_html_tag": "<img src=\"http:\/\/t1.ftcdn.net\/jpg\/00\/51\/97\/62\/110_F_51976254_dVCbgGVey5xEuLkvk1e4vhnmPqxI4J0X.jpg\" alt=\"Bumblebee species Bombus terrestris\" title=\"Photo: Bumblebee species Bombus terrestris\" width=\"110\" height=\"73\" \/>",
    "thumbnail_width": 110,
    "thumbnail_height": 73,
    "affiliation_link": "http:\/\/api.fotolia.com\/id\/51976254",
    "thumbnail_30_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/51\/97\/62\/30_F_51976254_dVCbgGVey5xEuLkvk1e4vhnmPqxI4J0X.jpg",
    "thumbnail_30_width": 30,
    "thumbnail_30_height": 20,
    "thumbnail_110_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/51\/97\/62\/110_F_51976254_dVCbgGVey5xEuLkvk1e4vhnmPqxI4J0X.jpg",
    "thumbnail_110_width": 110,
    "thumbnail_110_height": 73,
    "thumbnail_400_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/51\/97\/62\/400_F_51976254_dVCbgGVey5xEuLkvk1e4vhnmPqxI4J0X.jpg",
    "thumbnail_400_width": 400,
    "thumbnail_400_height": 267,
    "licenses": [
      {
        "name": "XS",
        "price": 1
      },
      {
        "name": "S",
        "price": 3
      },
      {
        "name": "M",
        "price": 5
      },
      {
        "name": "L",
        "price": 7
      },
      {
        "name": "XL",
        "price": 8
      },
      {
        "name": "XXL",
        "price": 10
      },
      {
        "name": "X",
        "price": 100
      }
    ]
  },
  "1": {
    "id": 44488015,
    "title": "Vintage Style Birds, Bees and Banners Vector Set",
    "media_type_id": 3,
    "creator_name": "artnerdluxe",
    "creator_id": 203491263,
    "thumbnail_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/44\/48\/80\/110_F_44488015_hvEpYPw8yILDsnAi6BChYWXtzmiH6jWd.jpg",
    "thumbnail_html_tag": "<img src=\"http:\/\/t1.ftcdn.net\/jpg\/00\/44\/48\/80\/110_F_44488015_hvEpYPw8yILDsnAi6BChYWXtzmiH6jWd.jpg\" alt=\"Vintage Style Birds, Bees and Banners Vector Set\" title=\"Vector: Vintage Style Birds, Bees and Banners Vector Set\" width=\"105\" height=\"110\" \/>",
    "thumbnail_width": 105,
    "thumbnail_height": 110,
    "affiliation_link": "http:\/\/api.fotolia.com\/id\/44488015",
    "thumbnail_30_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/44\/48\/80\/30_F_44488015_hvEpYPw8yILDsnAi6BChYWXtzmiH6jWd.jpg",
    "thumbnail_30_width": 29,
    "thumbnail_30_height": 30,
    "thumbnail_110_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/44\/48\/80\/110_F_44488015_hvEpYPw8yILDsnAi6BChYWXtzmiH6jWd.jpg",
    "thumbnail_110_width": 105,
    "thumbnail_110_height": 110,
    "thumbnail_400_url": "http:\/\/t1.ftcdn.net\/jpg\/00\/44\/48\/80\/400_F_44488015_hvEpYPw8yILDsnAi6BChYWXtzmiH6jWd.jpg",
    "thumbnail_400_width": 380,
    "thumbnail_400_height": 400,
    "licenses": [
      {
        "name": "XS",
        "price": 1
      },
      {
        "name": "S",
        "price": 3
      },
      {
        "name": "M",
        "price": 5
      },
      {
        "name": "L",
        "price": 7
      },
      {
        "name": "XL",
        "price": 8
      },
      {
        "name": "XXL",
        "price": 10
      },
      {
        "name": "V",
        "price": 5
      },
      {
        "name": "XV",
        "price": 40
      }
    ]
  }
}

これが私がこれまでに持っているクラスです:

Public Class mediaGallery
    Public Property nb_results As Integer
    Public Property results As Dictionary(Of String, mediaGalleryData)
End Class
Public Class mediaGalleryData
    Public Property id As Integer
    Public Property title As String
    Public Property creator_name As String
    Public Property creator_id As Integer
    Public Property media_type_id As Integer
    Public Property thumbnail_url As String
    Public Property thumbnail_width As Integer
    Public Property thumbnail_height As Integer
    Public Property thumbnail_html_tag As String
    Public Property thumbnail_30_url As String
    Public Property thumbnail_30_width As Integer
    Public Property thumbnail_30_height As Integer
    Public Property thumbnail_110_url As String
    Public Property thumbnail_110_width As Integer
    Public Property thumbnail_110_height As Integer
    Public Property thumbnail_400_url As String
    Public Property thumbnail_400_width As Integer
    Public Property thumbnail_400_height As Integer
    Public Property licenses As List(Of licensedata)
End Class
Public Class licensedata
    Public Property name As String
    Public Property price As Integer
End Class

私のRestSharpを消費するコード:

Public Function getUserGalleryMedias(page As Integer?, nb_per_page As Integer?, thumbnail_size As Integer?, id As String, detail_level As Integer?) As mediaGallery
    Dim request = New RestRequest("user/getUserGalleryMedias", Method.GET)
    If page.HasValue Then request.AddParameter("page", page.Value)
    If nb_per_page.HasValue Then request.AddParameter("nb_per_page", nb_per_page.Value)
    If thumbnail_size.HasValue Then request.AddParameter("thumbnail_size", thumbnail_size.Value)
    If Not String.IsNullOrEmpty(id) Then request.AddParameter("id", id)
    If detail_level.HasValue Then request.AddParameter("detail_level", detail_level.Value)

    Return Execute(Of mediaGallery)(request)
End Function
4

1 に答える 1

1

やるべきことはやり遂げましたが、少し遠回りをしなければなりませんでした。

wiki のRestSharp ドキュメントで提案されているように (ただし、あまり説明されていません)、IDeserializerこのクラスを特別に処理するように実装しました。RestSharp 内SimpleJsonでマークされているため、Web サイトに個別に追加する必要がありました。Friendそして、デシリアライザーを RestClient のハンドラーとして登録する代わりに、デシリアライザーがすべてのクラスを処理する必要がありましたExecute(Of T)が、T が厄介なクラスである 1 つのケースだけのために、API クラスのメソッド内で呼び出しました。

Execute(Of T)メソッド:

Public Function Execute(Of T As New)(request As RestRequest) As T
    Dim client = New RestClient()

    ' set up client with authenticator
    client.BaseUrl = BaseURL
    If String.IsNullOrEmpty(_sessionID) Then
        client.Authenticator = New HttpBasicAuthenticator(_apikey, "")
    Else
        client.Authenticator = New HttpBasicAuthenticator(_apikey, _sessionID)
    End If

    ' used on every request
    Dim response = client.Execute(Of T)(request)

    ' Check for exceptions or bad status code
    If response.ErrorException IsNot Nothing Then
        Throw response.ErrorException
    ElseIf response.StatusCode > 299 Then
        If response.Content.StartsWith("{""error""") Then
            Throw New Exception(String.Format("Status {0} {1} : {2}", response.StatusCode, response.StatusDescription, response.Content))
        Else
            Throw New HttpException(response.StatusCode, response.StatusDescription)
        End If
    End If

    ' Handle troublesome class
    If GetType(T).Equals(GetType(mediaGallery)) Then
        Dim fjs As New fotoliaJSONDeSerializer
        response.Data = fjs.Deserialize(Of T)(response)
    End If

    Return response.Data
End Function

デシリアライザー クラス:

    ''' <summary>
    ''' specific to the FotoliaAPI.mediaGallery we actually want to handle
    ''' </summary>
    ''' <param name="response"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function DeserializeMediaLibrary(response As IRestResponse) As FotoliaAPI.mediaGallery
        Dim result As New FotoliaAPI.mediaGallery

        ' turn to an iDictionary so we can readily enumerate keys
        Dim j As IDictionary(Of String, Object) = CType(SimpleJSON.SimpleJson.DeserializeObject(response.Content), IDictionary(Of String, Object))

        For Each key In j.Keys
            ' this top level key is a direct property
            If key = "nb_results" Then
                result.nb_results = j(key)
            Else
                ' all other keys become members of the list.
                ' Turn the value back to a string, then feed it back into SimpleJson to deserialize to the strongly typed subclass.
                result.media.Add( _
                    SimpleJSON.SimpleJson.DeserializeObject(Of FotoliaAPI.mediaGalleryData)( _
                        j(key).ToString))
            End If
        Next

        Return result

    End Function

    ' required but unimportant properties of IDeserializer
    Public Property DateFormat As String Implements Deserializers.IDeserializer.DateFormat
    Public Property [Namespace] As String Implements Deserializers.IDeserializer.Namespace
    Public Property RootElement As String Implements Deserializers.IDeserializer.RootElement
End Class
于 2013-06-06T04:55:58.933 に答える