JSON deserialization with C# problems - c#

I am having a problem reading the following JSON output in C#. I am not too familiar with JSON syntax, but it doesn't seem to be properly formatted, or I am unclear how to properly deserialize the data:
Array (
[label] => Column_Name
[column] => column0 )
15 0
Array (
[0] => 0
[1] => Array
(
)
[2] => 0 ) {"total":0,"entities":[],"page":0}
The code used in C# is simply:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Get;
request.Accept = "application/json";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Encoding enc = Encoding.GetEncoding(1252);
StreamReader configStream = new StreamReader(response.GetResponseStream(), enc);
var configuration = configStream.ReadToEnd();
JavaScriptSerializer jSerialize = new JavaScriptSerializer();
List[] operations = jSerialize.Deserialize<List[]>(configuration);
The error I am receiving is that 'Array' is not a valid JSON primitive. Assuming the syntax is correct from the JSON output, how do I derialize the data?

Your code should work for correct JSON input. The only part of your input that's correct json is: {"total":0,"entities":[],"page":0}

In one of my Silverlight project I've do this:
using Newtonsoft.Json; //add this library to refferences
ObservableCollection<MyClass> list = JsonConvert.DeserializeObject<ObservableCollection<MyClass>>(json)
Hope this help.

Related

.NET API Can't Find Data I Want

I'm trying to save two variables out of a json request but i'm just trying to get the first one working this is my request:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.majestic.com/api/json?app_api_key=KEY&cmd=GetIndexItemInfo&items=1&item0=http://www.majestic.com&datasource=fresh");
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
JObject jObject = JObject.Parse(reader.ReadToEnd());
JToken Trusty = jObject["DataTables"]["Results"]["Data"][2];
var newdomain = new Identifier { domain = model.domain, contact = model.contact, contactname = model.contactname, price = model.price, type = model.type, TrustFlow = Int32.Parse(Trusty.ToString()), CitationFlow = 65, RI = model.RI, MJTopicsID = model.MJTopicsID, UserTableID = model.UserTableID };
ViewBag.newdomain = newdomain;
db.Identifiers.Add(newdomain);
This returns this error:
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.'
I've also tried
Token Trusty = jObject["DataTables"]["Results"]["Data"]["TrustFlow"][0];
this returns:
'Accessed JArray values with invalid key value: "TrustFlow". Int32 array index expected.'
This is the json I tried separating it myself as on the url it just came as one long line:
{
"Code":"OK","ErrorMessage":"","FullError":"","FirstBackLinkDate":"2017-08-17","IndexBuildDate":"2017-11-20 10:51:56","IndexType":1,"MostRecentBackLinkDate":"2017-11-18","QueriedRootDomains":0,"QueriedSubDomains":0,"QueriedURLs":1,"QueriedURLsMayExist":0,"ServerBuild":"2017-10-25 14:33:44","ServerName":"QUACKYO","ServerVersion":"1.0.6507.24412","UniqueIndexID":"20171120105156-FRESH",
"DataTables":{
"Results":{
"Headers":{
"MaxTopicsRootDomain":30,"MaxTopicsSubDomain":20,"MaxTopicsURL":10,"TopicsCount":3
},
"Data":[{
"RefDomainTypeProtocolHTTPS":"228","CitationFlow":42,"TrustFlow":29,"TrustMetric":29,"TopicalTrustFlow_Topic_0":"Health/Animal","TopicalTrustFlow_Value_0":26,"TopicalTrustFlow_Topic_1":"Business","TopicalTrustFlow_Value_1":25,"TopicalTrustFlow_Topic_2":"Computers/Internet/Domain Names","TopicalTrustFlow_Value_2":24
}
]}}}
What am I doing wrong? Thanks.
Your Data property is an array of size 1. Arrays are 0 index based. So you will access the first item as someArray[0] and second item as someArray[1] and so on
To read the int value stored inside the TrustFlow property of the first item in the Data array, you can do this
int trustFlow = jObject["DataTables"]["Results"]["Data"][0]["TrustFlow"].Value<int>();
This should work for the JSON Data you provided in the question. Keep in mind that this code expects the data to be in that structure . For example, if your Data array does not have any item, or your Results does not have a Data property, the code will crash ( probably with a null reference exception). You can add the null check yourself before trying to access the value as needed.

Deserializing JSON Data with JSON.NET

I am having trouble working with an API, first time I've worked with one. I've managed to use GET to read the data I need and that part is working perfectly, now I need to deserialize the JSON data I am getting back, and I am using Newtonsoft's JSON .NET library. The problem seems to come when I deserialize the data as its exploding and the debugger isn't being helpful. I tried a few suggestions online but no go, so if someone can enlighten me it'd be appreciated. This is the code:
string url = "";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
string responseData = readStream.ReadToEnd();
var results = JsonConvert.DeserializeObject<dynamic>(responseData);
var id = results["id"].Value;
// var name = results.Name;
When I run it the debugger throws the following exception at the last line of code:
{"Accessed JArray values with invalid key value: \"id\". Array position index expected."}
I am fairly sure that ID exists in the data I am getting back.
Json data I am getting back from Smarty Streets:
[
{
"id": 0,
"candidate_index": 0,
"delivery_line_1": "1600 Amphitheatre Pkwy",
"last_line": "Mountain View CA 94043-1351",
"delivery_point_barcode": "940431351000",
"components": {
"primary_number": "1600",
"street_name": "Amphitheatre",
"street_suffix": "Pkwy",
"city_name": "Mountain View",
"state_abbreviation": "CA",
"zipcode": "94043",
"plus4_code": "1351",
"delivery_point": "00",
"delivery_point_check_digit": "0"
},
]
Your response is an array not a single object. So You should use
JArray results = JArray.Parse(responseData)
to parse the result (like results[0]["id"]). If you go the dynamic way then
dynamic results = JArray.Parse(responseData)
Now, you can use it like results[0].id
Another option is to "Paste JSON as classes" so it can be deserialised quick and easy.
Simply copy your entire JSON
In VS: Click Edit > Paste Special >
Paste JSON as classes
Here is a better explanation n piccas...
https://blogs.msdn.microsoft.com/webdev/2012/12/18/paste-json-as-classes-in-asp-net-and-web-tools-2012-2-rc/
Your result appears to be an array of objects, not an array itself. Try setting id to results["id"][0].Value and see if you get something.
See this: Accessed JArray values with invalid key value: "fields". Array position index expected

Parsing JSON Files with JSON.NET

I'm new to C# so I don't know how JSON Parsing in C# much. So I'm using JSON.net at the moment, so this is what I got:
WebClient c = new WebClient();
var data = c.DownloadString("http://media1.clubpenguin.com/play/en/web_service/game_configs/furniture_items.json");
JObject o = JObject.Parse(data);
button3.Text = "" + o["furniture_item_id"];
Is there any other way to parse JSON files with the JSON URL?
try
WebClient client = new WebClient();
string getString = client.DownloadString("http://media1.clubpenguin.com/play/en/web_service/game_configs/furniture_items.json");
JavaScriptSerializer serializer = new JavaScriptSerializer();
var listOfFurniture = serializer.Deserialize<List<Furniture>>(getString);
public class Furniture
{
public int furniture_item_id { get; set; }
}
There are many furniture_item_id's returned by the webclient. I've created a simple object that holds that value. 'listOfFurniture' is a List of type Furniture.
dynamic json = JsonConvert.DeserializeObject(data);
You can then access json as array by using an index or a key:
var someval = json["furniture_item_id"];
Note:
In case the request was not successful and thus you do not have any response to parse, this will probably end up in an JsonParseException so you might want to catch that.

Take the information from json

I'm trying to parse "VID" from this json data
{"response":[2,{"vid":165971367},{"vid":165971350}]}.
But it don't want to parse it. I think there is problem with "2" in json data. How to eliminate this figure?
Here is my code:
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("some json data");
string googleSearchText = await response.Content.ReadAsStringAsync();
JObject googleSearch = JObject.Parse(googleSearchText);
IList<JToken> results = googleSearch["response"].Children().ToList();
IList<SearchResult> searchResults = new List<SearchResult>();
If you were usng Json.Net and loaded that json into a JObject then you have a property called "response" so:
myJson["response"]
which is a JArray with 3 elements, so skip the first element.
.Skip(1)
Then you have IEnumerable and want property "vid", so something like:
var myVids = (from vids in myJObject["response"].Skip(1)
where vids["vid"] != null
select vids["vid"])
/* JSON
{"response":
[2,
{"vid":165971367},
{"vid":165971350}
]
}
*/
Of course, this is just the concept and you would need to adjust for real life.
You can skip the first item by using Skip method:
IList<JToken> results = googleSearch["response"].Skip(1).ToList();

How do I get properties in the array in this JSON string?

In the JSON string below, how do I access the values of the "at" and "current_value" properties within the "datastreams" array ?
In this example, there is only one datastream but in reality there could be many. I need to access the datastream by "id" property. Once I figure out this issue, I plan to use a where clause with the id == to the id of the desired datastream.
I tried using the approach discussed here, under "JSON in Windows 8 – A Simpler Approach" but it's not working.
In this code, json contains the JSON returned from the service I'm calling. prop is populated with a JsonArray. current results in an exception with an inner message of "JSON value not found"
var json = JsonObject.Parse(responseBodyAsText);
var prop = json.GetNamedArray("datastreams");
var current = from p in prop
select new
{
datastream = p.GetObject().GetNamedString("datastreams"),
datetime = p.GetObject().GetNamedString("at"),
value = p.GetObject().GetNamedString("current_value")
};
Here is the JSON string:
{
"title":"X",
"status":"X",
"creator":"X",
"datastreams":
[
{
"at":"x",
"max_value":"X",
"current_value":"X",
"id":"X",
"min_value":"X"
}
],
"location":{"exposure":"x","domain":"x","disposition":"x","lat":X,"lon":-X},
"created":"X",
"tags":["X"],
"feed":"X",
"private":"X",
"id":X,
"description":"X",
"version":"X",
"updated":"X"
}
datastream = p.GetObject().GetNamedString("datastreams")
The code above should return an array of objects. You'll need to loop through the array of objects to check the value of each object's "at" and "current_value" properties.
datastream return an array as you can notice by [ ] so:
datetime = datastream[0].at
value = datastream[0].current_value

Categories