Get value of JSON object in VB.net - json

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!

Related

UPDATE: Azure DevOps API: Sending commands to the REST API that are JSON instead of a URI

I am a little new to using the REST API for Azure DevOps and have it working fine where I can send my requests that are basically the URIs I see on the website for the API. Then I get that JSON response and de-serialize it into a class from the JSON response and am off running.
Below is an example of a function I use to get a Work Item by it's ID. It uses the URI from the website.
I can also test things by pasting the URI into my browser and then see the response.
My question is, How do I use the command for Updating the Workitem (Add Link for example) which is not a URI that I can test by pasting it into my browser. Instead it is a JSON message.
here is API Website which shows the JSON message needed to add a link to a work item.
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work%20items/update?view=azure-devops-rest-5.1#add-a-link
this is the JSON message they have there for updating a WorkItem Link:
[
{
"op": "test",
"path": "/rev",
"value": 3
},
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "System.LinkTypes.Dependency-forward",
"url": "https://dev.azure.com/fabrikam/_apis/wit/workItems/300",
"attributes": {
"comment": "Making a new link for the dependency"
}
}
}
]
Do I need a different function to send it the JSON message and then the function could return me the JSON Response? I can not find an example of what that function might look like.
Any Advice on how to send the JSON message instead of the URI to get a response would be greatly appreciated.
===================== UPDATE =====================
The one answer definitely helped me get this finally working.
I pasted in the updated function in case it helps anyone else.
I know it is tricky to find VB.NET samples for this. :)
THANKS!
UPDATED CODE==========================================================
Public Async Function GetRequestAsync(ByVal uri As String, Optional ByVal jsonMessageBody As String = "") As Task(Of String())
Dim client As HttpClient = New HttpClient()
SetUpHttpClient(client)
Dim statusCode As String = "NOTHING"
Dim responseBody As String = "NOTHING"
Try
If jsonMessageBody.Length > 0 Then
'#####################################################################
'### For all PATCH operations that have a URI and a JSON message ###
'#####################################################################
Dim patchValue = New StringContent(jsonMessageBody, Encoding.UTF8, "application/json-patch+json")
Dim method = New HttpMethod("PATCH")
Dim request = New HttpRequestMessage(method, uri) With {.Content = patchValue}
Dim response = client.SendAsync(request).Result
responseBody = response.Content.ReadAsStringAsync.Result()
Else
'#######################################################
'### For all other operations that have just a URI ###
'#######################################################
Using response As HttpResponseMessage = client.GetAsync(uri).Result
statusCode = response.StatusCode.ToString()
response.EnsureSuccessStatusCode()
responseBody = response.Content.ReadAsStringAsync().Result
End Using
End If
Catch
End Try
Dim answer As String() = {statusCode, responseBody}
Return answer
End Function
Public Function GetTestCase(organization As String, project As String, TestCaseID As String) As WorkItemApi
Dim dc As New DevCon.DevOpsConnector
Dim response As String() = dc.GetRequest($"https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{TestCaseID}?api-version=5.1&$expand=all")
If response(0) <> "OK" Then
Return Nothing
End If
Dim result As WorkItemApi = JsonConvert.DeserializeObject(Of WorkItemApi)(response(1))
Return result
End Function
Public Async Function GetRequestAsync(ByVal getRequest As String) As Task(Of String())
Dim client As HttpClient = New HttpClient()
SetUpHttpClient(client)
Dim statusCode As String = "NOTHING"
Dim responseBody As String = "NOTHING"
Try
Using response As HttpResponseMessage = client.GetAsync(getRequest).Result
statusCode = response.StatusCode.ToString()
' Console.WriteLine("Response: " & statusCode)
response.EnsureSuccessStatusCode()
responseBody = response.Content.ReadAsStringAsync().Result
End Using
Catch
End Try
Dim answer As String() = {statusCode, responseBody}
Return answer
End Function
You need to serialize the fields array into a json string. Check the following sample in C# using the HttpClient class:
public WorkItem CreateBugUsingHTTP()
{
string uri = _uri;
string personalAccessToken = _personalAccessToken;
string project = _project;
string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalAccessToken)));
Object[] patchDocument = new Object[4];
patchDocument[0] = new { op = "add", path = "/fields/System.Title", value = "Authorization Errors" };
patchDocument[1] = new { op = "add", path = "/fields/Microsoft.VSTS.TCM.ReproSteps", value = "Our authorization logic needs to allow for users with Microsoft accounts (formerly Live Ids) - http://msdn.microsoft.com/en-us/library/live/hh826547.aspx" };
patchDocument[2] = new { op = "add", path = "/fields/Microsoft.VSTS.Common.Priority", value = "1" };
patchDocument[3] = new { op = "add", path = "/fields/Microsoft.VSTS.Common.Severity", value = "2 - High" };
using (var client = new HttpClient())
{
//set our headers
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
//serialize the fields array into a json string
var patchValue = new StringContent(JsonConvert.SerializeObject(patchDocument), Encoding.UTF8, "application/json-patch+json");
var method = new HttpMethod("POST");
var request = new HttpRequestMessage(method, uri + "/" + project + "/_apis/wit/workitems/$Bug?api-version=5.1") { Content = patchValue };
var response = client.SendAsync(request).Result;
//if the response is successfull, set the result to the workitem object
if (response.IsSuccessStatusCode)
{
var workItem = response.Content.ReadAsAsync<WorkItem>().Result;
Console.WriteLine("Bug Successfully Created: Bug #{0}", workItem.Id);
return workItem;
}
else
{
Console.WriteLine("Error creating bug: {0}", response.Content);
return null;
}
}
}
You could get started from the documentation below:
https://learn.microsoft.com/en-us/rest/api/azure/devops/?view=azure-devops-rest-5.1
Public Async Function GetRequestAsync(ByVal uri As String, Optional ByVal jsonMessageBody As String = "") As Task(Of String())
Dim client As HttpClient = New HttpClient()
client.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
client.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Basic", _accessTokenHttpClient)
Dim statusCode As String = "NOTHING"
Dim responseBody As String = "NOTHING"
Try
If jsonMessageBody.Length > 0 Then
'#####################################################################
'### For all PATCH operations that have a URI and a JSON message ###
'#####################################################################
Dim patchValue = New StringContent(jsonMessageBody, Encoding.UTF8, "application/json-patch+json")
Dim method = New HttpMethod("PATCH")
Dim request = New HttpRequestMessage(method, uri) With {.Content = patchValue}
Dim response = client.SendAsync(request).Result
responseBody = response.Content.ReadAsStringAsync.Result()
Else
'#######################################################
'### For all other operations that have just a URI ###
'#######################################################
Using response As HttpResponseMessage = client.GetAsync(uri).Result
statusCode = response.StatusCode.ToString()
response.EnsureSuccessStatusCode()
responseBody = response.Content.ReadAsStringAsync().Result
End Using
End If
Catch
End Try
Dim answer As String() = {statusCode, responseBody}
Return answer
End Function

How to remove list square brackets from serialized json string

I'm calling a stored procedure using a controller.
var insert_query = entities.Database.SqlQuery<Call_Info>("exec [dbo].[insert_call_info] #call_id",
new SqlParameter("call_id", call_id)).ToList();
jsonResult = JsonConvert.SerializeObject(insert_query); // <-- using Newtonsoft.Json
The json string is the following:
"[{\"call_info_id\":18,\"call_id\":91389,\"user_id\":\"105bdbfb-d65a-42d3-ac79-c1e2575ed243\",\"call_arrive\":\"2020-04-03T21:51:24.797\",\"call_end\":\"2020-04-03T22:04:24.797\",\"info\":\"test\",\"AspNetUser\":null,\"Call\":null,\"StatusCode\":1}]"
Is there a way to remove the [ and ] brackets?
I want the json string to be:
{\"call_info_id\":18,\"call_id\":91389,\"user_id\":\"105bdbfb-d65a-42d3-ac79-c1e2575ed243\",\"call_arrive\":\"2020-04-03T21:51:24.797\",\"call_end\":\"2020-04-03T22:04:24.797\",\"info\":\"test\",\"AspNetUser\":null,\"Call\":null,\"StatusCode\":1}
var insert_query = entities.Database.SqlQuery<Call_Info>("exec [dbo].[insert_call_info] #call_id",
new SqlParameter("call_id", call_id)).ToList();
if(insert_query!=null && insert_query.Count()>0)
{
jsonResult = JsonConvert.SerializeObject(insert_query[0]);
}
This will serialise only 1st element so it wont have []

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 ...

How can i list the values of a Node in JSON ?

Say, I have a JSON that has an array of "Topics"
I need to list all "created_at" values of all the topics
without the other data , using the Chrome console
P.S : I'm Using JSONView
You can loop through the objects in your array and simply access the property created_at.
Example
var json = {
all_topics: [{
"created_at:" "2016-08-08T10:22:03.123Z",
"name": "topic1"
}, {
"created_at": "2016-08-08T11:43:06.963Z",
"name": "topic2"
}]
}
for (var topic of json.all_topics) {
console.log(topic.created_at);
}
You can use JSON.stringify to turn a JavaScript object into a JSON String, and JSON.parse to turn a JSON string into a JavaScript object.
var jsonString = JSON.stringify(json);
==> {"all_topics":[{"created_at":"2016-08-08T10:22:03.123Z","name":"topic1"},{"created_at":"2016-08-08T11:43:06.963Z","name":"topic2"}]}
var jsonObj = JSON.parse(jsonString);
==> Object {all_topics: Array[2]}
Alternatively, you could return a new array with the filtered property using Array.prototype.map:
var topics = json.all_topics.map(function(obj){
return obj.created_at;
});
==> ["2016-08-08T10:22:03.123Z", "2016-08-08T11:43:06.963Z"]

Parsing Json using Vb.net Json.NET

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.