60400

How to deserialize this JSON with VB.NET

Question:

I have this JSON data:

<blockquote>

{"asks":[["0.26039995",19.91610429],["0.26063345",3070.562292]],"bids":[["0.26000017",30381.45513902],["0.26000000",8299.1410574]],"isFrozen":"0","seq":50663190}

</blockquote>

I wrote this code:

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim wc As New WebClient Dim sURL As String = "https://poloniex.com/public?command=returnOrderBook&currencyPair=USDT_STR&depth=" & 2 Dim res As String = wc.DownloadString(New Uri(sURL)) Dim m As IEnumerable(Of Rootobject) = JsonConvert.DeserializeObject(Of IEnumerable(Of Rootobject))(res) End Sub Public Class Rootobject Public Property asks As asksDef() Public Property bids As bidsDef() Public Property isFrozen As String Public Property seq As Integer End Class Public Class asksDef Public Property priceAsk As String Public Property quantAsk As Integer End Class Public Class bidsDef Public Property priceBid As String Public Property quantBid As Integer End Class

I've pasted the JSON class with VB paste special. The question is: how to access to every ask, every bid and the isFrozen and seq values.

I got an error on this line:

Dim m As IEnumerable(Of Rootobject) = JsonConvert.DeserializeObject(Of IEnumerable(Of Rootobject))(res)

The error message I got is:

<blockquote>

An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[poloniexAPI.Rootobject]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

Path 'asks', line 1, position 8.

</blockquote>

I'm stuck again this time with this JSON model. How to proceed with this?

<blockquote>

{"BTC_BCN":{"id":7,"last":"0.00000042","lowestAsk":"0.00000043","highestBid":"0.00000042","percentChange":"0.00000000","baseVolume":"179.56364789","quoteVolume":"436786711.33832335","isFrozen":"0","high24hr":"0.00000043","low24hr":"0.00000039"},"BTC_BELA":{"id":8,"last":"0.00002091","lowestAsk":"0.00002097","highestBid":"0.00002091","percentChange":"-0.10831556","baseVolume":"12.57891843","quoteVolume":"579476.06165462","isFrozen":"0","high24hr":"0.00002345","low24hr":"0.00002088"}}

</blockquote>

Answer1:

The root cause of this specific error is that your JSON represents a single object (which contains some arrays and other info) but you are trying to deserialize it as if the whole thing were enumerable. However, fixing this will not solve the whole problem; there are a couple of other issues as well.

This JSON is a little odd because it uses an array to group together each price and quantity pair for the bids and asks, whereas an object seems like it would be more appropriate (and more easily consumable). Since Json.Net does not have a facility to automatically map an array into class properties by index, you will need to use a custom JsonConverter to deserialize this data properly. Also, the prices are represented as strings for some reason where they should be decimals like the quantity. This can be handled in the converter as well.

Before we get to the converter, let's fix your class definitions. Since the bids and asks use the same structure, I would recommend defining a common class for that. Both price and quantity properties should be declared as Decimal:

Public Class PriceQuantityPair Public Property price As Decimal Public Property quantity As Decimal End Class

Then define your root class like this:

Class RootObject Public Property asks As List(Of PriceQuantityPair) Public Property bids As List(Of PriceQuantityPair) Public Property isFrozen As String Public Property seq As Integer End Class

Here is the code for the converter, which will translate the array structure for each pair into a PriceQuantityPair instance:

Class PriceQuantityPairConverter Inherits JsonConverter Public Overrides Function CanConvert(objectType As Type) As Boolean Return objectType Is GetType(PriceQuantityPair) End Function Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object Dim ja As JArray = JArray.Load(reader) Dim pair As PriceQuantityPair = New PriceQuantityPair() pair.price = ja(0).ToObject(Of Decimal)() pair.quantity = ja(1).ToObject(Of Decimal)() Return pair 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

To use the converter, add a <JsonConverter> attribute to the PriceQuantityPair class like this:

<JsonConverter(GetType(PriceQuantityPairConverter))> Public Class PriceQuantityPair ... End Class

Finally, deserialize the JSON into the RootObject class like this:

Dim root As RootObject = JsonConvert.DeserializeObject(Of RootObject)(json)

Here is a demo: <a href="https://dotnetfiddle.net/dDHLtR" rel="nofollow">https://dotnetfiddle.net/dDHLtR</a>

Answer2:

As far as I understand your question. You can access the properties with the 'm' variable where you are storing the de serialized data. Ex: m.isFrozen, m.seq, m.bids() & m.asks().

Recommend

  • How to avoid multiple loops with multiple variables in R
  • Reading an image into an array?
  • I keep getting exception sometimes on System.Threading.Tasks.TaskCompletionSource how can i solve it
  • Dynamic language output for structure/internal table
  • Upgrading WP8 to Silverlight WP8.1, payload contains two or more files with same destination
  • Convert Json to List with .NET
  • XSLT 1.0: copy everything except certain nodes according to value and variable
  • Serializing a list of Object using Json.NET
  • Deserialize Dictionary
  • Google analytics measurement protocol session timeout and query time limits
  • Deploying a CodeRush plugin from the Community Site
  • Available space left on drive - WinAPI - Windows CE
  • Translating C# to PowerShell in InterIMAP
  • Exception creating JSON with LINQ
  • Undefined references when compiling gSOAP client
  • chrome.tabs.executeScript only fires when the Developer Console is open
  • Very simple C++ DLL that can be called from .net
  • Play WS (2.2.1): post/put large request
  • why do I get the error when installing the gem 'pg'? [duplicate]
  • ilmerge with a PFX file
  • Master page gives error
  • Different response to non-authenticated users and AJAX calls
  • How to convert from System.Drawing.Color to Excel.ColorFormat in C#? Change comment color
  • javascript inside java/jsp code
  • Hazelcast - OperationTimeoutException
  • To display the title for the current loaction in map in iphone
  • Google cloud sdk not working when python points python3
  • Akka Routing: Reply's send to router ends up as dead letters
  • Warning: Can't call setState (or forceUpdate) on an unmounted component
  • AT Commands to Send SMS not working in Windows 8.1
  • How to format a variable of double type
  • VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '
  • Android Studio and gradle
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • How do I configure my settings file to work with unit tests?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Is it possible to post an object from jquery to bottle.py?
  • Binding checkboxes to object values in AngularJs
  • How can i traverse a binary tree from right to left in java?