System.ArgumentException: invalid JSON primitive:. but only when browsing from mobile browser - c#

I have a simple test responsive aspx web page, that download json data and try to display results.
If i browse from the desktop/laptop computer i do not receive any error everything is ok, json data are deserialized and data are shown (i can list results about students) but if i open via mobile browser i receive System.ArgumentException: invalid JSON primitive:.
I dont know what can be the reason,or where to search the problem since in one case is working as espected
Json string is like this and is very simple:
{
"students":[
{
"studentName":"TEST- MORE TEST",
"MoreInfo":"sdpThP5YUMsaFfwOM7tj",
"Counter":"404",
"Age":"20"
}
]
}
I try to replace all dots in strings, remove all special characters and without results, i remove all records and only with one still dont work i cant figure out what can be wrong:
c# code that i use for desalinize:
using (var wc = new System.Net.WebClient())
{
//here i download my json data
string json = wc.DownloadString(download_url);
JavaScriptSerializer jss = new JavaScriptSerializer();
var myStudents = jss.Deserialize<studentList>(json);
foreach (student student in myStudents.students)
{
Response.Write(student.studentName + " " + student.Age </br>");
}
}
any help appreciated, thanks
Here is how is model defined:
public class student
{
public string studentName { get; set; }
public string MoreInfo { get; set; }
public string Counter { get; set; }
public string Age { get; set; }
}
public class studentList
{
public List<student> students { get; set; }
}

Related

Looping through a Json array (C#)

I have been working on some automated tests with selenium and I need to get some data out of a JSON file.
how can i go about coding this, i have this so far
string json = File.ReadAllText("myfilepath");
dynamic data = jsonConvert.DeserializeObject(json);
string x = data[0].CountryName.Value;
foreach(var CN in data.countryName)
{
var CountryName = CN.CountryName;
}
I am a bit stuck on getting data through to loop it
Any help would be amazing guys
Example Json :
[
{
"CountryLookupId":123,
"CountryName":data,
"CountryLocation": moredata
}
]
I am trying to loop through the CountryName,i need to loop through 31 things
With out testing it. make a object model:
public class CountryClass
{
[JsonProperty("CountryLookupId")]
[JsonConverter(typeof(ParseStringConverter))]
public long CountryLookupId { get; set; }
[JsonProperty("CountryName")]
public string CountryName { get; set; }
[JsonProperty("CountryLocation")]
public string CountryLocation { get; set; }
}
Than deserialize list of object model:
List<CountryClass> data = jsonConvert.DeserializeObject<List<CountryClass>>(json);
Finally you can loop over your list of country objects:
foreach(var cn in data)
{
var countryName = cn.CountryName;
}

Unable to use JSON data with Newtonsoft.Json in WPF

I am retrieving data from office365 api. The response is in JSON format. I want to get data like Id, DisplayName etc. into variables but not getting the right way to do it. Following this link. I'm new to API and JSON. Will Appreciate pointers as well towards best learning links.Sample JSON below for listing sub folders of Inbox folder.
Response JSON data.
{"#odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me/Folders('Inbox')/ChildFolders","value":
[
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmsdfsdfdDSFSDFDFDF=')",
"Id":"AAMkADBjMdfgdfgDFGDFGDFGdfGDFGDFGDFGGDzrACAAB4xqMmAAA=",
"DisplayName":"SampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":8,"TotalItemCount":94},
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEasdasdasdASDASDASDASDSADDASDASDAB4xqMnAAA=')",
"Id":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmOGZkNGRhZmIzNQAuAasdASDASDASDASEDASDASDxSEHjzrACAAB4xqMnAAA=",
"DisplayName":"AnotherSampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":21,"TotalItemCount":75}
]
}
The C# code using to parse JSON and find the required data.
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
throw new WebException(response.StatusCode.ToString() + ": " + response.ReasonPhrase);
string content = response.Content.ReadAsStringAsync().Result;
JObject jResult = JObject.Parse(content);
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
var folderName = results.Id;
var folderId = results.Name;
//Attempt two - [Not working - Throwing exception -
//Object reference not set to an instance of an object.]
var folderID = (string)jResult["odata.context"]["odata.id"][0]["Id"];
First create a class for your json object
public class RootObject
{
[JsonProperty(PropertyName = "#odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty(PropertyName = "#odata.id")]
public string dataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Then Json Convert the Json string to your RootObject if your are using Newtonsoft Json then Deserilaze by using
RootObject shortiee = JsonConvert.DeserializeObject<RootObject>("Your Json String");
private List<string> GetDisplayNames(JObject content)
{
var obj = Json.Parse(content);
var values = obj["value"].ToList();
var displayNames = new List<string>();
foreach (var value in values)
{
displayNames .Add(system["DisplayName"].ToString());
}
return displayNames;
}
This would return the names, for example, and you could do this for each value you need to retrieve. However, this does not require you to serialize/deserialize the json object before using it. It works, but is most likely not best practice.
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
Side note: There is no key called "odata.error" in your JSON data. So you're effectively calling something which will return null.
One of the ways to deserialise JSON is to create model classes for the objects you want to process and deserialise into them directly, eg. JsonConvert.DeserializeObject<Folder>(content). As you are talking to an Office365 API, you find documentation and examples here on how they are defined.
Taken your folder response as an example, your model for a single Folder could look like this:
public class Folder
{
[JsonProperty(PropertyName = "#odata.id")]
public string OdataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Note1: in your example, you get a response with list of folders, so have to adjust this accordingly.
Note2: you can use JsonProperty to define a mapping between a JSON property/key and a C# property as shwon for #odata.id.
However, you can also use the Outlook Client Library which would make it mostly unnecessary to deal with JSON data directly (which seems preferable, unless you have a very specific reason to deal with JSON directly).

Json deserialization with different variable names (FIXED Posted Solution)

Hello I'm working on a windows form application to enter in Magic The Gathering cards I have into a database for easy organization. In order to enter the card data fast I plan on using the MTG master card Json file which contains every card made and all of it's attributes. But the way they have the Json file doesn't seem to work well with the deserialization in Visual C#.
Here is what two entries look like:
{
"Air Elemental":{
(stuff that doesn't matter for the question)
},
"Ancestral Recall":{
. . .
}
}
As you can see the variable name for the data is different for every single one which is where the problem lies. I can't get C# to deserialize it correctly into a class because it wants the JsonProperty name and because it is different I can't really set it.
So if there is a way to specify that it doesn't need to have a specific name and it just stores what's placed in that variable I would really appreciate if you could tell me.
Thank you for any help you can provide.
SOLUTION
Thanks to Henrik I found out how to fix this problem. Here is what he posted:
dynamic data = JsonConvert.DeserializeObject(responseData);
IDictionary<string, JToken> cards = data;
foreach (var card in cards)
{
var key = card.Key;
var value = card.Value;
}
Which wasn't fully what I had to do but it laid out the ground of the solution. I figured out that the card.Value actually held all the Json text of the card so all I needed to do was use Json.DeserializeObject one more time but this time into my class that has all the values set to variables. Here's what it looks like
string json;
using (StreamReader sr = new StreamReader("G:/MTG Card Database/Files/AllCardsShort.json"))
{
json = sr.ReadToEnd();
sr.Close();
}
dynamic data = JsonConvert.DeserializeObject(json);
IDictionary<string, JToken> cards = data;
foreach (var card in cards)
{
CardData newCard = JsonConvert.DeserializeObject<CardData>(card.Value.ToString());
textBox1.Text = newCard.name; //Check to see if the name can be put into a textbox
break;
}
. . .
public class CardData
{
[JsonProperty("layout")]
public string layout { get; set; }
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("manaCost")]
public string manaCost { get; set; }
[JsonProperty("cmc")]
public string cmc { get; set; }
[JsonProperty("colors")]
public string[] colors { get; set; }
[JsonProperty("type")]
public string type { get; set; }
[JsonProperty("subtypes")]
public string[] subTypes { get; set; }
[JsonProperty("text")]
public string text { get; set; }
[JsonProperty("power")]
public string power { get; set; }
[JsonProperty("toughness")]
public string toughness { get; set; }
[JsonProperty("imageName")]
public string imageName { get; set; }
}
So again thank you Henrik for helping out. And thank you to everyone else that posted their idea as well!
Using Json.NET:
dynamic data = JsonConvert.DeserializeObject(responseData);
IDictionary<string, JToken> cards = data;
foreach (var card in cards)
{
var key = card.Key;
var value = card.Value;
}
Could this be what you are looking for? Check Tom Peplow's answer here
Deserialize JSON into C# dynamic object?
dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = stuff.Name;
string address = stuff.Address.City;

JSON ASP.NET Deserialization failing, getting null

From Javascript I send my object via string like so, data is what facebook FQL query returns:
var propData = new Object();
propData.d = data;
var jString = JSON.stringify(propData);
$('#<%=Hidden1.ClientID%>').val(jString);
$('#UpdatePanelTrigger').click();
Then, I receive this string on server side, display this JSON string in a label (which looks ok to me) and try to Deserialize it, code below.
public class Friends
{
public IList<Dictionary<string,string>> data {get; set;}
}
protected void UpdateTrigger_Click(object sender, EventArgs e)
{
JSON_out.Text = Hidden1.Value;
Friends fbookFriends = new System.Web.Script.Serialization.JavaScriptDerializer().Deserialize<Friends>(JSON_out.Text);
obj_check.Text = new System.Web.Script.Serialization.JavaScriptSErializer().Serialize(fbookFriends);
//The result of above line is {"data":null}
}
I don't understand why Deserializer refuses to convert this string to JSON.
Any help, would be greatly appreciated.
I.N.
PS: If it helps, My JSON string received on server, looks like this:
{"d":[{"uid":"XXXXXXXX","name":"Bro Number1","pic_square":"https://fbcdn-profile-a.akamaihd.net/beautiful_avatar.jpg"},{"uid":"XXXXX2","name":...
To be able to deserialize your json string in question your Friends class should be something like that
public class Friend
{
public string uid { get; set; }
public string name { get; set; }
public string pic_square { get; set; }
}
public class Friends
{
public List<Friend> d { get; set; }
}
But your comments says you have some top level fields like data (//The result of above line is {"data":null})

Parsing Json facebook c#

I am trying for many hours to parse a JsonArray, I have got by graph.facebook, so that i can extra values. The values I want to extract are message and ID.
Getting the JasonArry is no Problem and works fine:
[
{
"code":200,
"headers":[{"name":"Access-Control-Allow-Origin","value":"*"}],
"body":"{
\"id\":\"255572697884115_1\",
\"from\":{
\"name\":\"xyzk\",
\"id\":\"59788447049\"},
\"message\":\"This is the first message\",
\"created_time\":\"2011-11-04T21:32:50+0000\"}"},
{
"code":200,
"headers":[{"name":"Access-Control-Allow-Origin","value":"*"}],
"body":"{
\"id\":\"255572697884115_2\",
\"from\":{
\"name\":\"xyzk\",
\"id\":\"59788447049\"},
\"message\":\"This is the second message\",
\"created_time\":\"2012-01-03T21:05:59+0000\"}"}
]
Now I have tried several methods to get access to message, but every method ends in catch... and throws an exception.
For example:
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
foreach (var item in result)
{
Console.WriteLine(item.body.message);
}
throws the exception: System.Collections.Generic.Dictionary doesnt contain definitions for body. Nevertheless you see in the screenshot below, that body contains definitions.
Becaus I am not allowed to post pictures you can find it on directupload: http://s7.directupload.net/images/120907/zh5xyy2k.png
I don't havent more ideas so i please you to help me. I need this for a project, private, not commercial.
Maybe you could give me an phrase of code, so i can continue my development.
Thank you so far
Dominic
If you use Json.Net, All you have to do is
replacing
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
with
dynamic result = JsonConvert.DeserializeObject(json);
that's all.
You are not deserializing to a strongly typed object so it's normal that the applications throws an exception. In other words, the deserializer won't create an Anynymous class for you.
Your string is actually deserialized to 2 objects, each containing Dictionary<string,object> elements. So what you need to do is this:
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(s);
foreach(var item in result)
{
Console.WriteLine(item["body"]["message"]);
}
Here's a complete sample code:
void Main()
{
string json = #"[
{
""code"":200,
""headers"":[{""name"":""Access-Control-Allow-Origin"",""value"":""*""}],
""body"":{
""id"":""255572697884115_1"",
""from"":{
""name"":""xyzk"",
""id"":""59788447049""},
""message"":""This is the first message"",
""created_time"":""2011-11-04T21:32:50+0000""}},
{
""code"":200,
""headers"":[{""name"":""Access-Control-Allow-Origin"",""value"":""*""}],
""body"":{
""id"":""255572697884115_2"",
""from"":{
""name"":""xyzk"",
""id"":""59788447049""},
""message"":""This is the second message"",
""created_time"":""2012-01-03T21:05:59+0000""}}
]";
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
foreach(var item in result)
{
Console.WriteLine(item["body"]["message"]);
}
}
Prints:
This is the first message
This is the second message
I am using this simple technique
var responseTextFacebook =
#"{
"id":"100000891948867",
"name":"Nishant Sharma",
"first_name":"Nishant",
"last_name":"Sharma",
"link":"https:\/\/www.facebook.com\/profile.php?id=100000891948867",
"gender":"male",
"email":"nihantanu2010\u0040gmail.com",
"timezone":5.5,
"locale":"en_US",
"verified":true,
"updated_time":"2013-06-10T07:56:39+0000"
}"
I have declared a class
public class RootObject
{
public string id { get; set; }
public string name { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string link { get; set; }
public string gender { get; set; }
public string email { get; set; }
public double timezone { get; set; }
public string locale { get; set; }
public bool verified { get; set; }
public string updated_time { get; set; }
}
Now I am deserializing
JavaScriptSerializer objJavaScriptSerializer = new JavaScriptSerializer();
RootObject parsedData = objJavaScriptSerializer.Deserialize<RootObject>(responseTextFacebook );

Categories

Resources