Parsing Json using Vb.net Json.NET - json

Hey all I am getting the following error at random spots in my code:
Object reference not set to an instance of an object.
I know why I am getting it. It does not find the correct property that I have it looking for and therefore it gives the error. Some may have that property and some, as this error shows, may not.
What can I do in order to check first to make sure it has that property? Currently I just have a Try/catch method in place so it can keep going if it does find something that's not there.
For Each Row In json("data")
Try
thePostID = DirectCast(Row("id").ToString(), String)
thePostType = DirectCast(Row("type").ToString(), String)
thePosterID = DirectCast(Row("from")("id").ToString(), String)
thePosterName = DirectCast(Row("from")("name").ToString(), String)
Catch ex As NullReferenceException
msgbox("Did not find that particular property!")
End Try
Next
update
{
"data": [
{
"id": "102zzz533zz_10z52zz9zzzz94z3",
"from": {
"id": "102zzzzz95zzz7",
"name": "Jim zzzzz"
},
"likes": {
"data": [
{
"id": "85zzzzz35zzzz0",
"name": "Anna zzzzz"
},
{
"id": "10zzzz93z31zzzzz",
"name": "Vanessa zzzz zzzz"
},
{
"id": "1zzz44zzz48731z6",
"name": "Leta zzzzzz"
}
],
"paging": {
"cursors": {
"after": "MTAyMdfasdfwrtMTkyNg=",
"before": "ODUasdfasrU5Mwerw"
}
}
}
etc...
This JSON above follows in the same data path as all the others.
Using #Andrews code below:
thePostLikes = NullSafeSelect(Row, "likes.data.id")
If thePostLikes <> "NA" Then
For Each Row2 In json("likes")("data")
thePostLikesID += NullSafeSelect(Row2, "id") & ","
thePostLikesName += NullSafeSelect(Row2, "name") & ","
Next
End If
The value of thePostLikes is always Nothing

There may be a more graceful way to do this that's built in to JSON.NET, but here's a helper function that will just return Nothing if the path you supply doesn't exist:
Function NullSafeSelect(ByVal obj As JToken, ByVal path As String) As String
Dim result As String = Nothing
Dim value As JToken = obj.SelectToken(path, False)
if (value IsNot Nothing)
result = value.ToString()
End If
Return value
End Function
You would call it from your loop like this:
For Each row in json("data")
Dim thePostID As String = NullSafeSelect(row, "id")
Dim thePostType As String = NullSafeSelect(row, "type")
Dim thePosterId As String = NullSafeSelect(row, "from.id")
' ... etc
Next
Note that you do not need the DirectCast because the return type of the function is already String.

Related

Public Property Array Setting Values

I am using VB2010 and I want to without error or usigg Try, to check if a public property array index is existent. So, I am deserializing json data that looks like this:
{
"Title": "The Terminator",
"Year": "1984",
"Rated": "R",
"Released": "26 Oct 1984",
"Runtime": "107 min",
"Genre": "Action, Sci-Fi",
"Director": "James Cameron",
"Writer": "James Cameron, Gale Anne Hurd, William Wisher (additional dialogue)",
"Actors": "Arnold Schwarzenegger, Michael Biehn, Linda Hamilton, Paul Winfield",
"Plot": "A seemingly indestructible robot is sent from 2029 to 1984 to assassinate a young waitress, whose unborn son will lead humanity in a war against sentient machines, while a human soldier from the same war is sent to protect her at all costs.",
"Language": "English, Spanish",
"Country": "UK, USA",
"Awards": "6 wins & 6 nominations.",
"Poster": "https://m.media-amazon.com/images/M/MV5BYTViNzMxZjEtZGEwNy00MDNiLWIzNGQtZDY2MjQ1OWViZjFmXkEyXkFqcGdeQXVyNzkwMjQ5NzM#._V1_SX300.jpg",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "8.0/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "100%"
},
{
"Source": "Metacritic",
"Value": "84/100"
}
],
"Metascore": "84",
"imdbRating": "8.0",
"imdbVotes": "731,313",
"imdbID": "tt0088247",
"Type": "movie",
"DVD": "03 Sep 1997",
"BoxOffice": "N/A",
"Production": "Orion Pictures Corporation",
"Website": "http://www.terminator1.com/",
"Response": "True"
}
However, not all movies return the "Ratings" array. So, I want to be able to still set the array as Source imdb, rotten tomatoes, and metacritic and those Values as "N/A" if they don't exist. I wish the api would just return it as N/A it would be so much easier.
Here's my class for Ratings:
Public Class Ratings
Public Property Source As String
Public Property Value As String
End Class
Then my other class that returns the other values from the "Search" Array and it returns a good handful of different strings so I'll just skip to where I do ratings..
Public Class Results
Public Property Title As String
Public Property Year As String
'bunch more public property strings...
Public Property Rating As Ratings()
End Class
Now my form on load im just testing it out and of course I get an index out of bounds error if I try to set it manually or read a specific index because if the array isn't there, then the array indexes are non existent.
Imports System.Net
Imports System.Web.Script.Serialization
Dim Site As New WebClient()
Dim JSS As JavascriptSerializer = New JavascriptSerializer()
Dim strData As String = Site.DownloadString("http://www.omdbapi.com/?t=Terma&apikey=apikeygoeshere
Dim Movie As Results = JSS. Deserializs(Of Results) (strData)
And this is where I'm now stuck. I'm not sure what to do here. Any help would be much appreciated.
OK, this is what I did. Sorry, I am new here, and I wanted to just add a comment with my code but it's too long. However, if anyone knows a shorter way of doing this, please let me know.
Dim jss As JavaScriptSerializer = New JavaScriptSerializer()
Dim Site As New WebClient()
Dim strData As String = Site.DownloadString("http://www.omdbapi.com/?t=Terminator&y=1984&apikey=745dfb00")
Dim mvMovie As Results = New Results
mvMovie = jss.Deserialize(Of Results)(strData)
If mvMovie.Response = "True" Then
Dim imdbRatings As Ratings = New Ratings
Dim rtRatings As Ratings = New Ratings
Dim mtRatings As Ratings = New Ratings
Dim imdbSource As String = "Internet Movie Database"
Dim imdbValue As String = "N/A"
Dim rtSource As String = "Rotten Tomatoes"
Dim rtValue As String = "N/A"
Dim mtSource As String = "Metacritic"
Dim mtValue As String = "N/A"
If mvMovie.Ratings.GetUpperBound(0) = -1 Then
Array.Resize(mvMovie.Ratings, 3)
imdbRatings.Source = imdbSource
imdbRatings.Value = imdbValue
mvMovie.Ratings(0) = imdbRatings
rtRatings.Source = rtSource
rtRatings.Value = rtValue
mvMovie.Ratings(1) = rtRatings
mtRatings.Source = mtSource
mtRatings.Value = mtValue
mvMovie.Ratings(2) = mtRatings
ElseIf mvMovie.Ratings.GetUpperBound(0) = 0 Then
Array.Resize(mvMovie.Ratings, 3)
rtRatings.Source = rtSource
rtRatings.Value = rtValue
mvMovie.Ratings(1) = rtRatings
mtRatings.Source = mtSource
mtRatings.Value = mtValue
mvMovie.Ratings(2) = mtRatings
ElseIf mvMovie.Ratings.GetUpperBound(0) = 1 AndAlso mvMovie.Ratings(1).Source = "Rotten Tomatoes" Then
Array.Resize(mvMovie.Ratings, 3)
mtRatings.Source = mtSource
mtRatings.Value = mtValue
mvMovie.Ratings(2) = mtRatings
ElseIf mvMovie.Ratings.GetUpperBound(0) = 1 AndAlso mvMovie.Ratings(1).Source = "Metacritic" Then
Array.Resize(mvMovie.Ratings, 3)
rtRatings.Source = rtSource
rtRatings.Value = rtValue
mvMovie.Ratings(2) = mvMovie.Ratings(1)
mvMovie.Ratings(1) = rtRatings
End If
End If

extract element from an array

Hi I asked the similar question before: I have a large JSON file but the information I need is only small part of it. However, that part is a two dimensional array from "text"."size" part.Is any way I can loop each array and and get the number from what I have already?
{"widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500 }, "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center" }, "text": { "data": "Click Here", "size": [[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]], "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" } } }
I was taught from someone(thank you!) to use the following code
Option Explicit
Public Sub GetInfo()
Dim strJSON As String, json As Object, rowNumber As Long
Application.ScreenUpdating = False
Const PATH As String = "C:\Users\User\Desktop\test.JSON"
strJSON = GetJSONFromFile(PATH)
Set json = JsonConverter.ParseJson(strJSON)
Set json = json("widget")("text")
Dim key As Variant
With ThisWorkbook.Worksheets("Sheet1")
For Each key In json
rowNumber = rowNumber + 1
.Cells(rowNumber, 1) = key
.Cells(rowNumber, 2) = json(key)
Next key
End With
Application.ScreenUpdating = True
End Sub
Many Thanks
Seeing expected output would help. If you are simply after the items within the collection of collections returned by JsonConverter.ParseJson(strJSON)("widget")("text")("size") then the following will empty them.
Option Explicit
Public Sub GetInfo()
Dim strJSON As String, json As Object, rowNumber As Long, i As Long, j As Long
Const PATH As String = "C:\Users\User\Desktop\test.JSON"
strJSON = GetJSONFromFile(PATH)
Set json = JsonConverter.ParseJson(strJSON)("widget")("text")("size") '<collection of collections
With ThisWorkbook.Worksheets("Sheet1")
For i = 1 To json.Count
For j = 1 To json(i).Count
rowNumber = rowNumber + 1
.Cells(rowNumber, 1) = json(i)(j)
Next
Next
End With
End Sub
Public Function GetJSONFromFile(ByVal PATH As String) As String
Dim fso As Object, f As Object, outputString As String
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(PATH)
Do Until f.AtEndOfStream
outputString = f.ReadAll()
Loop
f.Close
GetJSONFromFile = outputString
End Function
JSON structure:
You can see the path down to the collection of collections in the JSON structure below. The {} are dictionaries and the [] are collections.

UWP - From Json string to Structure (Classes)

I receive a JSon string from WS. It's so long that I can't use Json2charp to parse it and receive the structurated class.
I want to parse the string with a command. How is it possible?
I don't know the classes so I can't use a command like:
Dim result = JsonConvert.DeserializeObject(Of MyClass.RootObject)(String_From_File)
Is it possible from the string to obtain the class without using json2charp site ?
For example, in vs.net if on the variable 'string_from_file' I choose 'Json Visualizer' and see all classes and data in correct mode.
How can I obtain the same in my code ?
I have installed Newtonsoft.json
If you cannot use the json to class mappers like NewtonSoft.Json. You can use the Windows.Data.Json api. It let you parse and extract the data you want from your JSON string.
JsonValue jsonValue = JsonValue.Parse("{\"Width\": 800, \"Height\": 600, \"Title\": \"View from 15th Floor\", \"IDs\": [116, 943, 234, 38793]}");
double width = jsonValue.GetObject().GetNamedNumber("Width");
double height = jsonValue.GetObject().GetNamedNumber("Height");
string title = jsonValue.GetObject().GetNamedString("Title");
JsonArray ids = jsonValue.GetObject().GetNamedArray("IDs");
You can find a sample in the Windows Universal Sample GitHub.
A complex object parsing is shown here. I've extracted the most relevant parts here. The JSON string is provided to the User constructor which is extracting what it needs and then delegating the parsing to the nested School constructor.
{
"id": "1146217767",
"phone": null,
"name": "Satya Nadella",
"education": [
{
"school": {
"id": "204165836287254",
"name": "Contoso High School"
},
"type": "High School"
},
{
"school": {
"id": "116138758396662",
"name": "Contoso University"
},
"type": "College"
}
],
"timezone": -8,
"verified": true
}
This JSON fragment is parsed with this code:
public User(string jsonString) : this()
{
JsonObject jsonObject = JsonObject.Parse(jsonString);
Id = jsonObject.GetNamedString(idKey, "");
IJsonValue phoneJsonValue = jsonObject.GetNamedValue(phoneKey);
if (phoneJsonValue.ValueType == JsonValueType.Null)
{
Phone = null;
}
else
{
Phone = phoneJsonValue.GetString();
}
Name = jsonObject.GetNamedString(nameKey, "");
Timezone = jsonObject.GetNamedNumber(timezoneKey, 0);
Verified = jsonObject.GetNamedBoolean(verifiedKey, false);
foreach (IJsonValue jsonValue in jsonObject.GetNamedArray(educationKey, new JsonArray()))
{
if (jsonValue.ValueType == JsonValueType.Object)
{
Education.Add(new School(jsonValue.GetObject()));
}
}
}
public School(JsonObject jsonObject)
{
JsonObject schoolObject = jsonObject.GetNamedObject(schoolKey, null);
if (schoolObject != null)
{
Id = schoolObject.GetNamedString(idKey, "");
Name = schoolObject.GetNamedString(nameKey, "");
}
Type = jsonObject.GetNamedString(typeKey);
}
If you cannot use the automatic mapping from NewtonSoft.Json, you have no other way than doing it yourself.
Is not so simple.
The Json i received is very complicated and have many class
So i can't use
double width = jsonValue.GetObject().GetNamedNumber("Width");
Inside class i have more ...

JSON.net string json into object

Hey all I am having difficultys in making this string JSON that I have into an object so that I can use it like this:
json("go")("to")("needed")("spot").toString
and get my value.
Currently the XML to JSON looks like this:
{
"?xml": {
"#version": "1.0",
"#encoding": "UTF-8"
},
"data": {
"recordCount": "1",
"metadata": {
"elementType": [
{
"name": "F_Paragraphtext",
"uiType": "textArea",
"dataType": "string",
"label": "Text String",
"dataLabel": ""
}
]
},
"records": {
"F_Form1": {
"#application_uid": "2a667c59-225c-4954-8e04-77bb083e5180",
"#uid": "61f876f4-9760-4013-85bb-37965cff1fb6",
"F_SingleLine": "test",
"F_Paragraphtext": "{\"Data\":{\"DevisionName\":\"testing service after added field\",\"DevisionCode\":\"test\",\"CodeInString\":\"test^test|4/15/2015|50%|test^test|4/15/2015|25%|test^test|4/23/2015|50%~test^test|4/23/2015|N/A|test^test|4/8/2015|N/A|test^test|3/31/2015|N/A~test^test|4/10/2015|N/A|test^test|5/1/2015|50%|test^test|4/18/2015|N/A~test^test|3/30/2015|50%|test^test|4/24/2015|50%|test^test|5/9/2015|100%~test^test|3/30/2015|25%|test^test|3/30/2015|100%|test^test|4/11/2015|75%\"}}"
}
}
}
}
And I am trying to get the value for F_Paragraphtext, #application_uid & #uid.
The VB.net code I have:
Dim doc1 As XmlDocument = New XmlDocument()
doc.LoadXml(serverResponse)
Dim json1 As String = Newtonsoft.Json.JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented)
jsreader = New Newtonsoft.Json.JsonTextReader(New StringReader(json1))
Try
json = DirectCast(New Newtonsoft.Json.JsonSerializer().Deserialize(jsreader), Newtonsoft.Json.Linq.JObject)
Catch ex As Exception
MsgBox(ex.Message)
End Try
For Each Row In json("data")("records")(febFormID)
Try
dName = json("#application_uid").ToString
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
While Row value is:
{"#application_uid": "2a667c59-225c-4954-8e04-77bb083e5180"}
The error falls on the dName = Row("#application_uid").ToString. The error is Object reference not set to an instance of an object..
Not quite sure what all I am missing in order to be able to retrieve the Row values but apparently its something....
...making this string JSON that I have into an object so that I can use it like this:
json("go")("to")("needed")("spot").toString
I am trying to get the value for F_Paragraphtext, #application_uid & #uid.
Dim jstr As String = File.ReadAllText(filename)
Dim myJ = JObject.Parse(jstr)
Console.WriteLine("{0} == {1}", "F_Paragraphtext",
myJ("data")("records")("F_Form1")("F_Paragraphtext"))
Console.WriteLine("{0} == {1}", "#application_uid",
myJ("data")("records")("F_Form1")("#application_uid"))
Console.WriteLine("{0} == {1}", "#uid",
myJ("data")("records")("F_Form1")("#uid"))
Output:
F_Paragraphtext == {"Data":{"DevisionName":"testing service after added field","DevisionCode":"test","CodeInString":"test^test|4/15/2015|50%|test^test|4/15/2015|25%|test^test|4/23/2015|50%~test^test|4/23/2015|N/A|test^test|4/8/2015|N/A|test^test|3/31/2015|N/A~test^test|4/10/2015|N/A|test^test|5/1/2015|50%|test^test|4/18/2015|N/A~test^test|3/30/2015|50%|test^test|4/24/2015|50%|test^test|5/9/2015|100%~test^test|3/30/2015|25%|test^test|3/30/2015|100%|test^test|4/11/2015|75%"}}
#application_uid == 2a667c59-225c-4954-8e04-77bb083e5180
#uid == 61f876f4-9760-4013-85bb-37965cff1fb6

Get value of JSON object in VB.net

I have the following code I would use in C#:
var tokenJson = JsonConvert.SerializeObject(tokenJsonString);
var jsonResult = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
var firstItem = jsonResult["data"][0];
However, I have a VB.NET client, and I have no idea how to translate it. I have tried different online tools without a result.
I have a JSON response like this:
"{\"token\":\"1edd6006-678a-4e6a-ab65-4fa60efa8632\"}"
And I just want the value of the token. In VB.NET ;)
Try this:
Dim tokenJson = JsonConvert.SerializeObject(tokenJsonString)
Dim jsonResult = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(jsonString)
Dim firstItem = jsonResult.Item("data").Item(0)
Cheers
Chosen awnser gives you the row { "token":"1edd6006-678a-4e6a-ab65-4fa60efa8632" }
Had the same problem and to get exactly the value of the token you can do:
Dim firstItem = jsonResult.Item("data").Item(0).Value(Of String)("token")
Outputs: "1edd6006-678a-4e6a-ab65-4fa60efa8632"
Hope it helps
Example JSON :
{
"fuits": [
],
"vehicles": [
{
"cars": [
{
"skoda": "2Lacks",
"maruti": 400000,
"neon": "3 Lacks",
},
{
}
]
}
}
If you want to acess the value for skoda in the above example json in VB.NET using JObject.Parse, Write it as :
Dim wallet As String = jsonobject("vehicles")(0)("cars")(0)("skoda").ToString()
Now you have 2Lacks in wallet!