I am working on a Windows Phone 8.1 application involving location. I am receiving Json data from my API. My API returns data that looks like:
[{
"country": "India",
"city": "Mall Road, Gurgaon",
"area": "Haryana",
"PLZ": "122002",
"street": "",
"house_no": "",
"POI": "",
"type": "17",
"phone": "",
"lng": 77.08972334861755,
"lat": 28.47930118040612,
"formatted_address": "Mall Road, Gurgaon 122002, Haryana, India"
},
{
"country": "India",
"city": "Mall Road, Kanpur",
"area": "Uttar Pradesh",
"PLZ": "208004",
"street": "",
"house_no": "",
"POI": "",
"type": "17",
"phone": "",
"lng": 80.35783410072327,
"lat": 26.46026740300029,
"formatted_address": "Mall Road, Kanpur 208004, Uttar Pradesh, India"
},
{
"country": "India",
"city": "Mall Road Area, Amritsar",
"area": "Punjab",
"PLZ": "143001",
"street": "",
"house_no": "",
"POI": "",
"type": "17",
"phone": "",
"lng": 74.87286686897278,
"lat": 31.64115178002094,
"formatted_address": "Mall Road Area, Amritsar 143001, Punjab, India"
},
{
"country": "India",
"city": "Vasant Kunj (Mall Road Kishan Garh), New Delhi",
"area": "Delhi",
"PLZ": "110070",
"street": "",
"house_no": "",
"POI": "",
"type": "18",
"phone": "",
"lng": 77.1434211730957,
"lat": 28.51363217008815,
"formatted_address": "Vasant Kunj (Mall Road Kishan Garh), New Delhi 110070, Delhi, India"
}]
I am deserializing my Json data and putting it into a class named LocationData. When I run my code, it gives me an error:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path
Where am I going wrong? Here is my code:
private async void GetAPIData()
{
string _serviceUrl = "https://api.myweblinkapiprovider/v2&q=" + UserRequestedLocation;
HttpClient client = new HttpClient();
HttpResponseMessage responce = await client.GetAsync(new Uri(_serviceUrl));
if (responce.Content != null)
{
var respArray = JObject.Parse(await responce.Content.ReadAsStringAsync());
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
settings.MissingMemberHandling = MissingMemberHandling.Ignore;
var rcvdData = JsonConvert.DeserializeObject<LocationData>(respArray.ToString(), settings);
UpdateMapData(rcvdData);
UpdateTextData(rcvdData);
}
}
I also tried to use a JArray. My code is as below:
private async void GetAPIData()
{
string _serviceUrl = "https://api.myweblinkprovider.com/v3?fun=geocode&lic_key=MyKey" + UserRequestedLocation;
HttpClient client = new HttpClient();
HttpResponseMessage responce = await client.GetAsync(new Uri(_serviceUrl));
JArray arr = JArray.Parse(await responce.Content.ReadAsStringAsync());
foreach (JObject obj in arr.Children<JObject>())
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
settings.MissingMemberHandling = MissingMemberHandling.Ignore;
var rcvdData = JsonConvert.DeserializeObject<LocationData>(arr.ToString(), settings);
UpdateMapData(rcvdData);
UpdateTextData(rcvdData);
}
}
It also gives me an error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MMI_SpeechRecog.Model.LocationData' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
The first part of your question is a duplicate of Why do I get a JsonReaderException with this code?, but the most relevant part from that (my) answer is this:
[A] JObject isn't the elementary base type of everything in JSON.net, but JToken is. So even though you could say,
object i = new int[0];
in C#, you can't say,
JObject i = JObject.Parse("[0, 0, 0]");
in JSON.net.
What you want is JArray.Parse, which will accept the array you're passing it (denoted by the opening [ in your API response). This is what the "StartArray" in the error message is telling you.
As for what happened when you used JArray, you're using arr instead of obj:
var rcvdData = JsonConvert.DeserializeObject<LocationData>(arr /* <-- Here */.ToString(), settings);
Swap that, and I believe it should work.
Although I'd be tempted to deserialize arr directly as an IEnumerable<LocationData>, which would save some code and effort of looping through the array. If you aren't going to use the parsed version separately, it's best to avoid it.
In this case that you know that you have all items in the first place on array you can parse the string to JArray and then parse the first item using JObject.Parse
var jsonArrayString = #"
[
{
""country"": ""India"",
""city"": ""Mall Road, Gurgaon"",
},
{
""country"": ""India"",
""city"": ""Mall Road, Kanpur"",
}
]";
JArray jsonArray = JArray.Parse(jsonArrayString);
dynamic data = JObject.Parse(jsonArray[0].ToString());
I ran into a very similar problem with my Xamarin Windows Phone 8.1 app. The reason JObject.Parse(json) would not work for me was because my Json had a beginning "[" and an ending "]". In order to make it work, I had to remove those two characters. From your example, it looks like you might have the same issue.
jsonResult = jsonResult.TrimStart(new char[] { '[' }).TrimEnd(new char[] { ']' });
I was then able to use the JObject.Parse(jsonResult) and everything worked.
The following worked for me to convert a list of objects to json.
using Newtonsoft.Json;
static void Main(string[] args)
{
List<eventResponse> o = new List<eventResponse>()
{
new eventResponse { acknowledge = "test" } ,
new eventResponse { acknowledge = "test 2" }
};
var json = JsonConvert.SerializeObject(o);
JArray jo = JArray.Parse(json);
Console.WriteLine(jo);
}
public class eventResponse
{
public string acknowledge { get; set; }
}
A delayed answer but if you have access to the API you can work on the javascript object to make it as JSon. Something like
var jsonAddresses = { "addresses":
[
{
"country": "India",
"city": "Mall Road, Gurgaon",
},
{
"country": "India",
"city": "Mall Road, Kanpur",
}
]};
Then in C#
JObject Addjson = JObject.Parse(model.YourAddressesSampleJSONStr);
Related
Example JSON, for example say I want the quote and author values. I wasn't able to get them unless I built a model around the JSON, which I'm not wanted to do as it would be more time consuming.
{
"success": {
"total": 1
},
"contents": {
"quotes": [
{
"quote": "Plant your own garden and decorate your own soul, instead of waiting for someone to bring you flowers.",
"length": "102",
"author": "Veronica A. Shoffstall",
"tags": [
"flowers",
"inspire",
"self-help",
"soul"
],
"category": "inspire",
"language": "en",
"date": "2022-12-22",
"permalink": "https://theysaidso.com/quote/veronica-a-shoffstall-plant-your-own-garden-and-decorate-your-own-soul-instead-o",
"id": "LQbKQGxVA2rcH4lIwn6OIweF",
"background": "https://theysaidso.com/img/qod/qod-inspire.jpg",
"title": "Inspiring Quote of the day"
}
]
},
"baseurl": "https://theysaidso.com",
"copyright": {
"year": 2024,
"url": "https://theysaidso.com"
}
}
My test example code with URL below. I tried it with Dynamic Object but can never get to the string.
try
{
private static readonly HttpClient _httpClient = new HttpClient();
// Make the API request
var response = _httpClient.GetAsync("https://quotes.rest/qod?language=en").Result;
response.EnsureSuccessStatusCode();
// Do something with the response
var value11 = response.Content.ReadAsStringAsync().Result;
var gett = JsonConvert.DeserializeObject<dynamic>(value11);
var quote= gett.contents.quotes.quote;
return quote;
}
catch (Exception ex)
{
quote = ex.Message;
return quote;
}
Looking at the JSON structure the quotes property is an array and as such you should use
var quote = gett.contents.quotes[0].quote;
Assuming that deserialization was not the cause of the failure.
There is no json convert error. quotes is array you can access gett .contents.quotes[0].quote.
Tips; you don't need to json convert and ReadAsString you can easily use like response.Content.ReadFromJsonAsync().Result?.contents.quotes[0].quote
With this code:
var button = Value.ForStruct(new Struct{
Fields={
["type"] = Value.ForString("postback"),
["title"] = Value.ForString("Call Representative"),
["payload"] = Value.ForString("+15105551234"),
}
});
var inPayload = Value.ForStruct(new Struct{
Fields ={
["buttons"] = Value.ForList(button),
["text"] = Value.ForString("try the postback"),
["template_type"] = Value.ForString("button"),
}
});
var attachment = Value.ForStruct(new Struct{
Fields ={
["payload"] = inPayload,
["type"] = Value.ForString("template"),
}
});
var msg = Value.ForStruct(new Struct{
Fields ={
["attachment"] = attachment,
});
Payload = new Struct{
Fields ={
["facebook"] = msg
}
I was able to create the following json:
"payload": {
"facebook": {"attachment": {
"payload": {
"buttons": [ {
"type": "postback",
"title": "Call Representative",
"payload": "+15105551234"
}],
"text": "try the postback",
"template_type": "button"
},
"type": "template"
}}
Now I need to create the following other format but I dont find how to do it:
"payload": {
"message": "Yes I did it"
"platform": "kommunicate",
"attachment": {
"payload": {
"buttons": [ {
"type": "postback",
"title": "Call Representative",
"payload": "+15105551234"
}],
"text": "try the postback",
"template_type": "button"
},
"type": "template"
}
I really dont find how to eliminate the first "facebook": { element and leave only:
{
"message": "Yes I did it",
"platform": "kommunicate",
"attachment":
And include message and platform at the same level. Here is the complete json I will like to generate:
"payload": {
"platform": "kommunicate",
"message": "Yes I did it",
"attachment": {
"payload": {
"buttons": [ {
"type": "postback",
"title": "Call Representative",
"payload": "+15105551234"
}],
"text": "try the postbackggggggg",
"template_type": "button"
},
"type": "template"
}
If you want to take an object and convert it to json I would recommend taking a look at Newtonsoft Json.Net library. They have plenty of examples that might help you. There is also protobuf.net library for serializing to protobuf instead of json.
Both libraries are used in similar ways, you create a class with appropriate properties and set the values you want. You will need multiple classes for nested types as in your example. Protobuf requires you to annotate the properties with attributes, while this is optional for json.net. You then send the object to the serialization library and get a string or binary data representing your object. This kind of object is often called a Data Transfer Object (DTO), since the only purpose it has is to aid in serialization or/and transfering the data to another system.
This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 5 years ago.
I am new in unity and I need to download data from JSON. I successfully download JSON data but I am not able to parse the JSON. I have use Boomlagoon Asset to serialize my JSON. Here is my code.
void Start() {
string url = "http://www.windmillinfotech.com/carlife/carlife_api/get_workshop";
WWWForm form = new WWWForm();
form.AddField("district", "Dhaka");
form.AddField("thana", "Mirpur");
form.AddField("service_type", "car");
WWW www = new WWW( url, form );
StartCoroutine (request(www));
}
IEnumerator request (WWW www) {
yield return www;
if(!string.IsNullOrEmpty(www.error)) {
print( "Error : " + www.error );
} else {
string serviceData = www.text;
JSONObject json = JSONObject.Parse(serviceData);
print ("\n\n\n\n"+json["workshop_dtls_result"]);
}
}
and my JSON result is like follows,
{
"success": true,
"workshop_dtls_result": [
{
"id": "141",
"user_id": "",
"store_id": null,
"updated_by": null,
"workshop_name": "Okay Auto Engineering",
"workshop_email": "",
"workshop_address": "Section -10, Block - A, Plot - 9, Main Road, Mirpur, Dhaka-1216. Behind the graveyard, 01712978222",
"district": "Dhaka",
"thana": "Mirpur",
"post_code": "",
"contact_person": "Sabir Hossain",
"contact_number": "01712978222",
"alternative_number": "",
"service_type_car": "Car",
"service_type_bus": "",
"service_type_bike": "",
"workshop_photo_1": "",
"workshop_photo_2": "",
"workshop_photo_3": "",
"latitude": "",
"longitude": "",
"create_date": "2017-01-01",
"active_status": "Active",
"workshop_services": null,
"lubricants_available": "No",
"lubricant_products": null
},
{
"id": "142",
"user_id": "",
"store_id": null,
"updated_by": null,
"workshop_name": "Ali Automobile ",
"workshop_email": "",
"workshop_address": "Section -11, Block- D, Avenue-1 Plot-14, Mob: 01925920115",
"district": "Dhaka",
"thana": "Mirpur",
"post_code": "",
"contact_person": "Mohammad Ali",
"contact_number": "01925920115",
"alternative_number": "",
"service_type_car": "Car",
"service_type_bus": "",
"service_type_bike": "",
"workshop_photo_1": "",
"workshop_photo_2": "",
"workshop_photo_3": "",
"latitude": "",
"longitude": "",
"create_date": "2017-01-01",
"active_status": "Active",
"workshop_services": null,
"lubricants_available": "No",
"lubricant_products": null
}
]
}
Now my question is that how can I get each values of id, workshop_name etc? Please help me to parse this JSON data.
Thanks in advance.
Please refer to below code as reference:
using SimpleJSON;
var N = JSON.Parse(the_JSON_string);
var versionString = N["version"].Value; // versionString will be a string containing "1.0"
var versionNumber = N["version"].AsFloat; // versionNumber will be a
float containing 1.0
var name = N["data"]["sampleArray"][2]["name"];// name will be a string containing "sub object"
Here the JSON string (the_JSON_string) is as follows:
{
"version": "1.0",
"data": {
"sampleArray": [
"string value",
5,
{
"name": "sub object"
}
]
}
}
Note that according to our experience, SimpleJson works on both Android and iOS, and NewtonSoft does NOT work in some iOS devices. If your app is mobile app, you should not use NewtonJson.
Add Newtonsoft.Json from nuGet package manager to your solution.
Add reference inside the unity file
in server side serialize your list like: JsonConvert.SerializeObject(your object);
in client side do like this : JSON.Parse(your result)
I have a Json String that I get from a web service; it has a list of collections, each collection represents an object, for example:
[ // Root List
[ // First Collection : Team Object
{
"id": 1,
"team_name": "Equipe Saidi",
"is_active": true,
"last_localisation_date": "2015-05-06T13:33:15+02:00"
},
{
"id": 3,
"team_name": "Equipe Kamal",
"is_active": true,
"last_localisation_date": "2015-05-06T09:22:15+02:00"
}
],
[// Second Collection : user Object
{
"id": 1,
"login": "khalil",
"mobile_password": "####",
"first_name": "Abdelali",
"last_name": "KHALIL",
"email": "KHALIL#gmail.com",
"role": "DR",
"is_active": true,
"charge": false
},
{
"id": 2,
"login": "ilhami",
"mobile_password": "####",
"first_name": "Abdellah",
"last_name": "ILHAMI",
"email": "ILHAMI#gmail.com",
"role": "DR",
"is_active": true,
"charge": false
}
]
]
My actual code (not working of course ):
public async Task TeamsAndMobileUsers()
{
string data = "";
IList<User> MobileUsersList = new List<User>();
IList<Team> TeamsList = new List<Team>();
try
{
data = await GetResponse(PATH + TEAMS_USERS_URL);
TeamsList = JsonConvert.DeserializeObject<List<Team>>(data);
MobileUsersList = JsonConvert.DeserializeObject<List<User>>(data);
// Inserting
await SetAchievedActions(TeamsList);
}
catch (Exception e) {
_errors.Add(e.Message);
}
}
I use Json.net and C#. I can't find a solution, I've read that I should use JsonReader and set its SupportMultipleContent property to true but I don't know how to implement that solution.
As #YeldarKurmangaliyev already said, your json has two different objects, I think you can do something like this:
var j = JArray.Parse(data);
TeamsList = JsonConvert.DeserializeObject<List<Team>>(j[1].ToString());
MobileUsersList = JsonConvert.DeserializeObject<List<User>>(j[2].ToString());
have you tried http://json2csharp.com/ to generate contract classes for that json? also, first and last parenthesis gives a not valid JSON
You need to create 4 classes
1st class TeamObject : Variable(id,team_name,is_active,last_localisation_date)
2nd class UserObject : Variable (id, login,mobile_password,first_name, last_name , email, role,is_active,charge)
3rd class RootList: Variable ( arraylist<TeamObject> obj, arraylist<UserObject > obj2)
4th class RootClass : Variable(arraylist<RootList> obj)
Gson gson=new Gson();
RootClass dtomodel = gson.fromJson(data , RootClass .class);
This parsing done using Gson Library
i have json string as :
{
"data": [
{
"id": "100000045402409_310121622373595",
"from": {
"name": "Ritesh Ranjan",
"id": "100000045402409"
},
"message": "greatttttttttttttt ab jaooooooooo",
"picture": "http://external.ak.fbcdn.net/safe_image.php?d=AQAGY5rsr5AeM5PI&w=90&h=90&url=http\u00253A\u00252F\u00252Fwww.ndtv.com\u00252Fnews\u00252Fimages\u00252Ftopstory_thumbnail\u00252FChidambaram_2G_120.jpg",
"link": "http://www.ndtv.com/article/india/2g-scam-chidambaram-verdict-expected-shortly-huge-implications-for-govt-173168",
"name": "2G scam: Chidambaram verdict expected shortly, huge implications for govt",
"caption": "www.ndtv.com",
"description": "A Delhi court handling the 2G spectrum allocation scam trial is likely to decide today whether Union Home Minister P Chidambaram should be made a co-accused in the case for allegedly allowing former Telecom Minister A Raja to gift mobile network licenses and scarce second-generation or 2G spectrum a...",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yD/r/aS8ecmYRys0.gif",
"type": "link",
"application": {
"name": "Links",
"id": "2309869772"
},
"created_time": "2012-02-04T11:02:22+0000",
"updated_time": "2012-02-04T11:02:22+0000"
},
{
"id": "100003303253347_132959650157476",
"from": {
"name": "Suman Dey",
"id": "100003303253347"
},
"message": "Check out this article I was reading on biNu. 2G verdict: Chidambaram off the hook, government exhales",
"type": "status",
"application": {
"name": "biNu",
"canvas_name": "binuapp",
"namespace": "binuapp",
"id": "378628085054"
},
"created_time": "2012-02-04T10:54:19+0000",
"updated_time": "2012-02-04T10:54:19+0000"
},
.....
//Continued...
Now i want to parse it using c#
i have used :
WebClient client = new WebClient();
string Json = client.DownloadString("https://graph.facebook.com/search?q=2g+verdict+Chidambaram&type=post");
System.IO.StreamWriter SW = new System.IO.StreamWriter(JsonDestFile);
SW.WriteLine(Json);
System.IO.StreamWriter SW1 = new System.IO.StreamWriter(ValuesDestFile);
JObject o = JObject.Parse(Json);
var postTitles = from p in o["data"].Children()["from"]
select p["name"].Values<string>();
foreach (var item in postTitles)
{
SW1.WriteLine(item);
}
SW1.WriteLine(name);
But i am not able to get any name values at all.
Its giving me error : Cannot access child value on Newtonsoft.Json.Linq.JValue.
Please suggest me how can i parse the above json for values of id, name, id (from one) , message
I got it working...
var postTitles = from p in JO["data"].Children()
select new
{
Names = (string)p["from"]["name"],
Msg = (string)p["message"],
};
Using this LINQ i can access the required data.
I haven't used the LINQ to JSON API, but if you don't insist on using it you can simply create a class that models the data in your JSON payload and then use the following method:
Newtonsoft.Json.JsonConvert.DeserializeObject<YourDataModelClass>()
you need to deseriralise the json string as shown below
public static T Deserialise<T>(string json)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
var serialiser = new DataContractJsonSerializer(typeof(T));
return (T)serialiser.ReadObject(ms);
}
}
Return type is you class
public class MyData
{
public string id { get; set;}
public string name{ get; set;}
public string message{ get; set;}
}
you can check full details : Parse JSON in C#
This also will work
JObject hh = JObject.Parse(jsonstring);
string name = (string)hh["Name"];