本文介绍了RestSharp 反序列化在根元素下包含值和字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建 POCO 类,以便 RestSharp 可以反序列化特定的 JSON 结果.症结似乎是根对象同时包含一个 nb_results 键和一个其他键的字典(0:"、1:"等,每个键都有一个复数值).

I am trying to construct POCO classes so that RestSharp can deserialize a particular JSON result.The sticking point seems to be that the root object contains both a nb_results key, and a dictionary of other keys ("0:", "1:", etc. each with a complex value).

我已经尝试过 Dictionary(Of Integer, mediaGalleryData) 和 Dictionary(Of String, mediaGalleryData).两者都不起作用.nb_results 总是序列化,但字典从来没有.

I have tried both Dictionary(Of Integer, mediaGalleryData) and Dictionary(Of String, mediaGalleryData). Neither works. nb_results always serializes, but the dictionary never does.

{
  "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 的代码:

My RestSharp-consuming code:

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

推荐答案

我已经完成了我需要做的事情,但我还需要走很长一段路.

I've accomplished what I needed to do, but I had to go a bit of the long way around.

如 wiki 上的 RestSharp 文档中所建议(但没有很好地解释),我实现了IDeserializer来专门处理这个类.我不得不将 SimpleJson 单独添加到网站,因为它在 RestSharp 中被标记为 Friend.而不是将我的解串器注册为 RestClient 的处理程序,这将需要我的解串器来处理所有类,我只是在我的 API 类的 Execute(Of T) 方法中调用它,仅用于单个T 是麻烦类的情况.

As suggested (but not very well explained) in the RestSharp documentation on the wiki, I implemented IDeserializer to handle this class specially. I had to add SimpleJson to the website separately, since it is marked Friend inside RestSharp. And instead of registering my deserializer as a handler with the RestClient, which would have required my deserializer to handle ALL classes, I just invoked it inside my API class's Execute(Of T) method, for just the single case where T is the troublesome class.

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

这篇关于RestSharp 反序列化在根元素下包含值和字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-01 05:31