How to deserilize array of json Object in c# - c#

Hi I want to read Id from JSON object which returns from Web Service :
[{"id":11,"username":"test5"}]
Code:
HttpResponseMessage response = null;
using (response = httpClient.PostAsync(url, content).Result)
{
try
{
response.EnsureSuccessStatusCode(); //200 Ok
string responJsonText = response.Content.ReadAsStringAsync().Result;
JObject res = JObject.Parse(responJsonText);
//if ((int)res["id"][0] > 0)
// {
var uid = (int)res["id"][0];
if (uid > 0)
{
return uid;
}
else
{ return 0; }
// }
// else
//{ return 0; }
}
How i can read the Id and username from Json Response using C#?
I get an exception with the following message:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path

Solution 1 - deserialize into C# models:
You can create a model that matches your json structure:
public class User
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("username")]
public string Username { get; set; }
}
And then deserialize the json string, using Newtonsoft.Json nuget package as follows:
string json = #"[{""id"":11,""username"":""test5""}]";
var users = JsonConvert.DeserializeObject<List<User>>(json);
Solution 2 - parsing the json using JArray
string json = #"[{""id"":11,""username"":""test5""}]";
JArray array = JArray.Parse(json);
int id = array.First["id"].Value<int>();
string username = array.First["username"].Value<string>();
I'm assuming the array will contain at least 1 element and there will be an id and username property. Proper error handling code should be added.

Related

How to fix error: JsonSerializationException: Cannot deserialize the current JSON object

This is what the body looks like:
{
"_total": 3,
"users": [
{
"username": "person1",
"points": 3
},
{
"username": "person2",
"points": 2
},
{
"username": "person3",
"points": 1
}
]
}
The code:
public class UserData
{
public string username { get; set; }
public int points { get; set; }
}
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<List<UserData>>(body);
foreach (UserData userdata in data)
{
Debug.Log(userdata.username + ": " + userdata.points);
}
}
The Error:
JsonSerializationException: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[UserData]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
The class does not match the JSON structure, hence you are getting JsonSerializationException Exception.
Your model should look something like that:
public class RootClass
{
public int _total { get; set; }
public List<User> users { get; set; }
}
public class User
{
public string username { get; set; }
public int points { get; set; }
}
Than you can do this:
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<RootClass>(body);
foreach (User userdata in data.users)
{
Debug.Log(userdata.username + ": " + userdata.points);
}
}
you can parse a json string at first and after this to deserialize it to a list of UserData
var data = JObject.Parse(body)["users"].ToObject<List<UserData>>();

How to pass incoming integer parameter value in json request while making a POST request

Making a POST request for the API, passing incoming json body as hardcoded string. Fine with all hardcoded values, only need to pass ID based on incoming parameter incomingID (int)
Checked couple of articles/questions, but didn't any clear answer. Please suggest/guide how to replace this hardcoded value 123456 with incoming parameter value (incomingID)
Replace field in Json file with some other value
How to replace placeholders inside json string?
private void CallAPI(int incomingID)
{
const string apiURL = "API URL"; // some test API
string getInfoResult = string.Empty;
try
{
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(apiURL);
webrequest.Method = "POST";
webrequest.ContentType = "application/json";
using (var streamWriter = new StreamWriter(webrequest.GetRequestStream()))
{
string json = "{\"Information\":{\"messageHeader\":{\"message\":\"getInfo\",\"transactionDate\":\"2021-05-11T12:05:54.000\", \"transactionID\":\"2021-05-15T12:05:54.000-12345\",\"payLoadFormat\":\"V1\",\"ID\":123456}}}"; //pass this incomingID based on parameter value
streamWriter.Write(json);
}
HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse();
Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
StreamReader responseStream = new StreamReader(webresponse.GetResponseStream(), enc);
getInfoResult = responseStream.ReadToEnd();
webresponse.Close();
}
catch (Exception ex)
{
throw ex;
}
}
To make this, you can use simple interpolation:
string json = $"{{\"Information\":{{\"messageHeader\":{{\"message\":\"getInfo\",\"transactionDate\":\"2021-05-11T12:05:54.000\", \"transactionID\":\"2021-05-15T12:05:54.000-12345\",\"payLoadFormat\":\"V1\",\"ID\":{incomingID}}}}}}}"
Note that open and close brackets should be repeated twice to escape them. But, this is weird and not so common way to make JSON strings. Better use serialization to achieve your goal. For an example, use Newtonsoft.Json nuget to (de)serialize your objects. What you need to do:
Create your models as separate classes:
PayloadFormat.cs
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] // this string will force your enum serialize as "V1" instead of "0"
public enum PayloadFormat
{
V1,
V2,
V3
}
MessageHeader.cs
public class MessageHeader
{
public MessageHeader(string message, DateTime transactionDate, string transactionId, PayloadFormat payloadFormat, int id)
{
Message = message;
TransactionDate = transactionDate;
TransactionId = transactionId;
PayloadFormat = payloadFormat;
Id = id;
}
public string Message { get; set; }
public DateTime TransactionDate { get; set; } // change type if you need to
public string TransactionId { get; set; } // change type if you need to
public PayloadFormat PayloadFormat { get; set; } // change type if you need to
public int Id { get; set; }
}
Information.cs
public class Information
{
public Information(MessageHeader messageHeader)
{
MessageHeader = messageHeader;
}
public MessageHeader MessageHeader { get; set; }
}
Create an instance of your Information class:
var information = new Information(new MessageHeader("getInfo", DateTime.Now, $"{DateTime.Now}-12345", PayloadFormat.V1, incomingID));
Serialize your string (make sure you are using Newtonsoft.Json;):
var json = JsonConvert.SerializeObject(information);
Then use your json as you need to. The result will be:
{
"MessageHeader": {
"Message": "getInfo",
"TransactionDate": "2022-05-17T19:45:33.2161326+05:00",
"TransactionId": "17.05.2022 19:45:33-12345",
"PayloadFormat": "V1",
"Id": 5
}
}

exception when deserializing json object

I am attempting to deserialize some simple json into the below objects
public class Car
{
public int car_id { get; set; }
public string name { get; set; }
}
public class RootObject
{
public List<Car> cars { get; set; }
}
This is the call I make
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://localhost/WebApiServer/Reference/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("cars").Result;
if (response.IsSuccessStatusCode)
{
HttpContent httpContent = response.Content;
string responseString = httpContent.ReadAsStringAsync().Result;
//error happens here
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(responseString);
}
this is the value of response string from debugger in VS
"\"{ \\\"cars\\\": [{\\\"car_id\\\":46,\\\"name\\\":\\\"Ford-Fiesta\\\"]}}\""
and this is the exception
//exception
Error converting value "{ "cars": [{"car_id":46,"name":"Ford-Fiesta"]}}" to type 'WebApiJson.Program+RootObject'. Path '', line 1, position 62.
this is the json - I am reading it from a file
{ "cars": [{"car_id":46,"name":"Ford-Fiesta"}]}
I have run out of ideas
EDIT:
I just tried
string serializeObject = JsonConvert.SerializeObject(text);
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(serializeObject);
and it is giving me the same problem
EDIT 2
my controller returning the json
public string Cars()
{
string text = System.IO.File.ReadAllText("json.txt");
string serializeObject = JsonConvert.SerializeObject(text);
Debug.WriteLine(serializeObject);
// this fails
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(serializeObject);
return JsonConvert.SerializeObject(text);
}
string text = System.IO.File.ReadAllText("json.txt");
//this line is WRONG!!
string serializeObject = JsonConvert.SerializeObject(text);
//this fails because serializeObject is a double serialized string
//which you try to deserialize to RootOject
var deserializeObject = JsonConvert.DeserializeObject<RootObject>(serializeObject);
return JsonConvert.SerializeObject(text);
You are serializing string into a string.
string serializeObject = JsonConvert.SerializeObject(text);
This is wrong, you should be deserializing to an object.
RootObject obj = JsonConvert.DeserializeObject<RootObject>(text);
This is why your Deserialize fails, because you serialize your initial json into a second string, then try to deserialize it into a RootObject.
Your controller should read something like this
public RootObject Cars()
{
string text = System.IO.File.ReadAllText("json.txt");
RootObject serializeObject = JsonConvert.DeserializeObject<RootObject>(text);
return serializeObject;
}

Error Json deserialization and List<>

I'm trying to deserialize some JSON response. With simple response I've no problem but with a complex response I get this error:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[APIEffilogics.Usuari+Node]' because
the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
To fix this error either change the JSON to a JSON array (e.g.
[1,2,3]) or change the deserialized type so that it is a normal .NET
type (e.g. not a primitive type like integer, not a collection type
like an array or List) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to
deserialize from a JSON object.
It seems that I have a problem with the type of I put when deserialize the string. The JSON string is like this:
{
nodes: [
{
id: 5,
global_id: 5,
description: "Oven",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 2,
nodetype_id: 1
},
{
id: 39,
global_id: 39,
description: "Fridge",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 8,
nodetype_id: 1
}, ...
],
limit: 10,
offset: 0
}
And those are the classes:
public class Node : Usuari //Estructura nodes
{
[JsonProperty("limit")]
public int limit { get; set; }
[JsonProperty("offset")]
public int offset { get; set; }
[JsonProperty("nodes")]
public List<Node_sub> nodes_sub { get; set; }
}
public class Node_sub : Node
{
[JsonProperty("id")]
public string nid { get; set; }
[JsonProperty("global_id")]
public string gid { get; set; }
[JsonProperty("description")]
public string descrip { get; set; }
[JsonProperty("room_id")]
public string rid { get; set; }
[JsonProperty("floor_id")]
public string fid { get; set; }
[JsonProperty("client_id")]
public string cid { get; set; }
[JsonProperty("building_id")]
public string bid { get; set; }
[JsonProperty("nodemodel_id")]
public string model { get; set; }
[JsonProperty("nodetype_id")]
public string type { get; set; }
}
The code is:
public void Request(string url, string metode, string value)
{
try
{
//Enviem la petició a la URL especificada i configurem el tipus de connexió
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.KeepAlive = true;
myReq.Headers.Set("Cache-Control", "no-store");
myReq.Headers.Set("Pragma", "no-cache");
myReq.Headers.Set("Authorization", usuari.token_type + " " + usuari.access_token);
myReq.ContentType = "application/json";
if (metode.Equals("GET") || metode.Equals("POST"))
{
myReq.Method = metode; // Set the Method property of the request to POST or GET.
if (body == true)
{
// add request body with chat search filters
List<paramet> p = new List<paramet>();
paramet p1 = new paramet();
p1.value = "1";
string jsonBody = JsonConvert.SerializeObject(value);
var requestBody = Encoding.UTF8.GetBytes(jsonBody);
myReq.ContentLength = requestBody.Length;
//myReq.ContentType = "application/json";
using (var stream = myReq.GetRequestStream())
{
stream.Write(requestBody, 0, requestBody.Length); //Enviem el cos de la petició
}
body = false;
}
}
else throw new Exception("Invalid Method Type");
//Obtenim la resposta del servidor
HttpWebResponse myResponse = (HttpWebResponse)myReq.GetResponse();
Stream rebut = myResponse.GetResponseStream();
StreamReader readStream = new StreamReader(rebut, Encoding.UTF8); // Pipes the stream to a higher level stream reader with the required encoding format.
string info = readStream.ReadToEnd();
if (tipus == 0) jsonclient = JsonConvert.DeserializeObject<List<Usuari.Client>>(info);
else if (tipus == 1) jsonedif = JsonConvert.DeserializeObject<List<Usuari.Building>>(info);
else if (tipus == 2) jsonplanta = JsonConvert.DeserializeObject<List<Usuari.Floor>>(info);
else if (tipus == 3) jsonhab = JsonConvert.DeserializeObject<List<Usuari.Room>>(info);
else if (tipus == 4) jsonnode = JsonConvert.DeserializeObject<List<Usuari.Node>>(info);
}
catch (WebException ex)
{
// same as normal response, get error response
var errorResponse = (HttpWebResponse)ex.Response;
string errorResponseJson;
var statusCode = errorResponse.StatusCode;
var errorIdFromHeader = errorResponse.GetResponseHeader("Error-Id");
using (var responseStream = new StreamReader(errorResponse.GetResponseStream()))
{
errorResponseJson = responseStream.ReadToEnd();
}
//var errorCode = JsonObject.Parse(errorResponseJson).Object("responseStatus")["errorCode"];
//var errorMessage = JsonObject.Parse(errorResponseJson).Object("responseStatus")["message"];
}
}
Why I'm having this error? List<Usuari.Node> is an array that contains all the items of JSON message. I try to fix the error but I'm not able to find and answer. How can I fix it?
Thanks
The service returns just one Node, instead of an array of Nodes with one element. To solve this problem, you can use one of these approaches:
Change the service so it always returns an array (by wrapping the result before returning it).
If 1. is not an option: Differentiate the different response types in the client (check if the response is an array and if not, tell the serializer to parse a single Node instead of a list) and either handle the single object differently or just wrap it in a list and then proceed as if the server returned it like that.

How to parse a JSON array C#?

So after doing a web request, I get this JSON string back:
{"status":"okay","result":[{"id":8810,"country":"IE","region":"07","city":"Dublin","latitude":53.3331,"longitude":-6.2489,"comment":"407367 donkeys"},{"id":9688,"country":"IE","region":"04","city":"Cork","latitude":51.8986,"longitude":-8.4958,"comment":"454765 donkeys"},{"id":9963,"country":"IE","region":"06","city":"Donegal","latitude":54.65,"longitude":-8.1167,"comment":"315518 donkeys"}]}
I'm not sure how to parse it. I have a City class that has id, country, region etc, and I would like to be able to save each one separately in a list so I can add them to a List View for an app.
I have tried this:
JObject jobj = JObject.Parse(jsonString);
JToken jstatus = jobj["status"];
JToken jresult = jobj["result"];
status = (String)jstatus;
JArray arrayOfCities = JArray.Parse(jsonString);
if (status.Equals("okay"))
{
foreach (JObject o in arrayOfCities.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
id = p.Name + p.Value.ToString();// (String)jresult["id"];
country = (String)jresult["country"];
region = (String)jresult["region"];
city = (String)jresult["city"];
latitude = (String)jresult["latitude"];
longitude = (String)jresult["longitude"];
comment = (String)jresult["comment"];
}
}
}
However I keep getting parse errors in it. I tried a few things, but none end up working.
How could I parse each part of the array separately and save it to a City List.
Thanks
You should use DeserializeObject. Here's an example:
public class CitiesResponse
{
public string Status { get; set; }
public List<City> Result { get; set; }
}
var response = JsonConvert.DeserializeObject<CitiesResponse>(jsonString);
// response.Result is your list of cities

Categories

Resources