Capture json data from Steam API - c#

So I what I am trying to do is capture/extract specific data from Steams API for dota2 heroes. I am using C# to do this with this method.
https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=2D13D618DA712015812E970165632F02&language=en_us
{
"result": {
"heroes": [
{
"name": "npc_dota_hero_antimage",
"id": 1,
"localized_name": "Anti-Mage"
},
]
}
This is the code I have been trying with:
WebClient c = new WebClient();
var data = c.DownloadString("https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=2D13D618DA712015812E970165632F02&language=en_us");
JObject o = JObject.Parse(data);
string heroname = (string)o["name"];
But it only returns an error saying the value of "heroname" is null.
Any ideas?

o is going to be an object that contains one key: result. o["result"] will in turn contain a key called heroes. o["result"]["heroes"] is an array of objects. So o["result"]["heroes"][0] will be the first item, and o["result"]["heroes"][0]["name"] is the name from the first item.

Related

Cannot access a jObject token in c#

I have the following json called 'originalJson'
{
"user_active": true,
"user_firstname": "Bob",
"user_lastname": "Tester",
"user_displayname": "Bobby",
"user_primary_email": "bob#tester.com",
"user_login_enabled": true,
"user_profile": {
"user_locale": "en-gb",
"user_lang": "en-gb"
},
"user_identities": [],
"user_roles": [
{
"app_id": "74a019c9-7171-4af0-a773-3984edaa35ca",
"context_uuid": "74a019c9-7171-4af0-a773-3984edaa35ca",
"context_type": "context_application",
"role_oid": "test_role_a",
"role_start_date": "2020-06-27T13:00:00Z",
"role_end_date": "2021-06-27T13:00:00Z"
}
]
}
and I am trying to replace the role_start_date and role_end_date values.
I have tried the following
JObject jObj = JObject.Parse(originalJson);
jObj["user_roles"]["role_start_date"] = somenewstartDate;
jObj["user_roles"]["role_end_date"] = somenewendDate;
However it is failing and doesn't like the "jObj["user_roles"]["role_start_date"]". I thought it would be pretty simple to do, I must be missing something.
Any ideas?
The property "user_roles" is an array of objects not a single object. You are trying to set a property value in the first entry in that array, so you need to do:
jObj["user_roles"][0]["role_start_date"] = somenewstartDate;
jObj["user_roles"][0]["role_end_date"] = somenewendDate;

Read value from nested Json object

I am trying to read a value from a nested Json object, but I am getting a Parse error:
My Json object:
{
"MessageId": "f6774927-37cf-4608-b985-14a7d86a38f9",
"Time": "2017-04-06T16:28:38.0719933+02:00",
"Data":
{
"ID":
{
"value": "0008044834"
},
"Carrier":
{
"value": 0
},
"Tool":
{
"value": 0
}
}
}
var myJsonString = File.ReadAllText(_currentDictory.FullName + #"\test\" + completeFilename);
var myJObject = JObject.Parse(myJsonString);
var serial = myJObject.SelectToken("Data.ID").Value<String>();
System.InvalidCastException
HResult=0x80004002
Message=Cannot cast Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JToken.
Source=Newtonsoft.Json
Reading other values such as "MessageID" works withou any problems, but as soon as I try to get "Data.XYZ" I am getting the error above.
You need to add value to your json path:
var serial = myJObject.SelectToken("Data.ID.value").Value<String>();
Your current path selects JObject containing one property named value and you can't convert it directly to string.
MessageId is a string. So you can directly read its value.
Data on the other hand contains objects (see the { and } ). Therefor you need to use
var serial = myJObject.SelectToken("Data.ID.value").Value<String>();
Also see:
Getting 'Cannot cast Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JToken' when retrieving items from JSON

C# - parse JSON with dynamic and access property name with colon

When getting a JSON with property with :
i.e.
{
"root": {
"sim:names": [{
"name": "Tom"
},
{
"name": "David"
}]
}
}
I'm using Newtonsoft Dynamic parse.
var data = JsonConvert.DeserializeObject<dynamic>(jsonString);
I'm trying to access
data.root.sim:names
But getting compilation error "Invalid expression term ':'"
How can I access it?
You should convert it to object
var data = JsonConvert.DeserializeObject<Object>(jsonString);
And access it like this:
var value = ((JObject)data)["root"]["sim:names"];

Querying a complex Json with Linq

I would like to make a Linq query in a json string.
little info about what i'm trying to do. At work we have a web based schedule system which don't have a support for windows 8 and windows phone 8 app. That is why I decided to make one. Using HttpClient I get an http string which I then convert to xml then Json. As you can see from the (Link below, the 'TheWholeJsonString.json' file) the property name and JSON object name is not informative and the JSON file is complicated. That is why I decided to extract some of the values from the JSON string and write a totally new JSON file that include the extracted JSON values in a more informative way.
The [tr] array in the original JSON file have several JSON Objects. Inside the 'VeryShorten.json' file in the linked folder you can see the structure of one of those objects (OBS! there is objcet with different structure). The only thing I hide is the Name and E-Mail address of RL ppl.
I also attached 'ShortenVersion.json' which is only a shorten version of the whole json string, just to make it easy to handle.
Json data sample
{
"#class": "odd",
"td": [
{
"#class": "user",
"#onmouseover": "userInfo('149');",
"#onmouseout": "userInfo(0);",
"#onmousemove": "moveSlotInfo();",
"#text": " ",
"a": {
"#href": "Name3#dreamnet.com",
"#text": "Name3"
}
},
.
.
.
In C# if i try the following code (which is not Linq)
var jObject = JObject.Parse(jString); //jString is 'TheWholeJsonString.json' file in the attached link
var jObj = jObject["tbody"]["tr"][8];
var gh = jObj.Value<JToken>("td").Children().First().Value<JToken>("a").Value<string>("#text");
i can get the value of '#text' which is *'Name3'.
However if i try the following code (Linq version):-
var jObject = JObject.Parse(jString);
var jCollection = jObject["tbody"]["tr"].Children();
var test = from userToken in jCollection
where
userToken.Value<JToken>("td")
.Children()
.First()
.Value<JToken>("a")
.Value<string>("#text")
.Contains("Name3")
select (string)userToken["#text"];
foreach (var item in test)
{
var fgh = item.Type;
}
It will break on the first iteration of foreach loop with the following error msg "Cannot access child value on Newtonsoft.Json.Linq.JValue". I really now what is causing the problem, but i don't know how to solve it. The problem is that not every token inside jCollection have a 'td' object and even if the token have 'td' object it is not Always it have token 'a'. You can see this either in the 'TheWholeJsonString.json' or 'ShortVersion.json' files which i attached in the link.
Hope this will explain more info.
So the question is:- Anyone can help to solve this problem?
You can use SelectTokens method. Notice false as second parameter - don't generate error if element is not found.
var jObject = JObject.Parse(jString);
var trList = jObject["tbody"]["tr"];
string[] names = trList.SelectMany(tr => tr.SelectTokens("td[0].a.#text", false))
.Select(t => t.Value<string>())
.ToArray();
You can easily query with LINQ like this
considering this JSON
{
"items": [
{
"id": "10",
"name": "one"
},
{
"id": "12",
"name": "two"
}
]
}
putting it in a variable called json like this,
JObject json = JObject.Parse("{'items':[{'id':'10','name':'one'},{'id':'12','name':'two'}]}");
you can select all ids from the items where name is "one" using the following LINQ query
var Ids =
from item in json["items"]
where (string)item["name"] == "one"
select item["id"];

Create javascript object which will convert to JSON then to Dictionary<string, bool>

I have a C# class which contains a property of Dictionary
I have a web-page which contains a list of items i need to cast into this dictionary.
My web-site will send the list up to my C# MVC application as JSON and then JsonConvert.Deserialise the JSON into my Dictionary object.
JsonConvert.Deserialise is expecting JSON in the following format:
"MyVariableName":{
"Item 1":true,
"Item 2":true
}
I need to know how i can construct this object in JavaScript.
So far, i have tried this without luck:
var items = [];
var v = $('#Items :input');
$.each(v, function(key, val) {
items.push({
key: val.value,
value: val.checked
});
});
JSON.stringify(v, null, 2);
But this returns a json converted value of:
"MyVariableName": [
{
"key": "Item 1",
"value": true
},
{
"key": "Item 2",
"value": true
}]
Which in turn does not de-serialize to my dictionary.
Thanks
Don't make an array; make an object:
var items = {};
$('#Items :input').each(function(i, val) {
items[val.value] = val.checked;
});
You have to use javascript serialization
One more thing you have different value int key, value pair like string and Boolean type, so you have to use Dictionary type.
And JavaScriptSerializerobject you will get System.Web.Script.Serialization name space of System.Web.Extensions.dll, v4.0.30319 assembly.
var jSerializer = new JavaScriptSerializer();
var newList= jSerializer.Deserialize<Dictionary<string,object>>(newData);

Categories

Resources