问题描述
我正在尝试构建 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 反序列化在根元素下包含值和字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!