here is my JSON response:
[
{
"Id": 25,
"CreateDate": "2020-09-26T12:25:27.917",
"Title": "Second TV Repair",
"categoryTitle": "Tv Repair",
"FirstName": "Sample FirsName",
"LastName": "Sample LastName"
} ]
here is my deserilizer class:
public class ServicemanHistory
{
public int Id { get; set; }
public DateTime CreateDate { get; set; }
public string Title { get; set; }
public string categoryTitle { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Here is my restsharp request method:
public static async Task<List<ServicemanHistory>> getServiceManHistory()
{
string url = "https://myapi.net";
string token = Settings.token;
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + token);
var response = await client.ExecuteAsync<List<ServicemanHistory>>(request);
Console.WriteLine("**** response is:" + response.Content);
if(response.IsSuccessful)
{
Console.WriteLine("SUCCESS!!!");
return response.Data;
} else
{
return null;
}
}
I get success printed in my console and I get the json returned from response.Content, but response.Data is always null. I did the same using NewtonSoft and that didn't fix it. And I tried using a wrapper for JSON array inside my deserializer class and didn't work either.
My attempt using NewtonSoft:
public static async Task<List<ServicemanHistory>> getServiceManHistory()
{
string url = "https://myapi.net";
string token = Settings.token;
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + token);
var response = await client.ExecuteAsync(request);
Console.WriteLine("**** response is:" + response.Content);
var result = JsonConvert.DeserializeObject<List<ServicemanHistory>>(response.Content);
if(response.IsSuccessful)
{
Console.WriteLine("SUCCESS!!!");
return result;
} else
{
return null;
}
}
I get the following error when trying to deserialize using NewtonSoft:
Newtonsoft.Json.JsonSerializationException
Message=Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List
o 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.
Related
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>>();
Good afternoon.
I need to deserialize the fields in JSON so that I can work with them as variables. I wrote a getter and setter for fields, loaded json from the url, but at the deserialization stage I get an error
"Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'GetDataFromUrl.JsonData' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly."
How do I correctly specify data for deserialization?
This type of JSON:
[
{
"Date": "2020-01-30",
"CountProblem": 10,
"Users": 8,
}
]
Code:
class JsonData
{
public DateTime Date { get; set; }
public int CountProblem { get; set; }
public int Users { get; set; }
}
class Report
{
static void Main(string[] args)
{
WebClient client = new WebClient();
var urlResponse = client.DownloadString("//my url");
JsonData jsondata = JsonConvert.DeserializeObject<JsonData>(urlResponse);
DateTime date = jsondata.Date;
int problemCount = jsondata.CountProblem;
int Users = jsondata.Users;
Console.WriteLine(Date + "," + CountProblem + "," + Users);
}
Your json string represents array not a single object, so try:
List<JsonData> jsondata = JsonConvert.DeserializeObject<List<JsonData>>(urlResponse);
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;
}
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.
I'm trying to do a very simple example of using RestSharp's Execute method of querying a rest endpoint and serializing to a POCO. However, everything I try results in a response.Data object that has all properties with a NULL value.
Here is the JSON response:
{
"Result":
{
"Location":
{
"BusinessUnit": "BTA",
"BusinessUnitName": "CASINO",
"LocationId": "4070",
"LocationCode": "ZBTA",
"LocationName": "Name of Casino"
}
}
}
Here is my test code
[TestMethod]
public void TestLocationsGetById()
{
//given
var request = new RestRequest();
request.Resource = serviceEndpoint + "/{singleItemTestId}";
request.Method = Method.GET;
request.AddHeader("accept", Configuration.JSONContentType);
request.RootElement = "Location";
request.AddParameter("singleItemTestId", singleItemTestId, ParameterType.UrlSegment);
request.RequestFormat = DataFormat.Json;
//when
Location location = api.Execute<Location>(request);
//then
Assert.IsNotNull(location.LocationId); //fails - all properties are returned null
}
And here is my API code
public T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient();
client.BaseUrl = Configuration.ESBRestBaseURL;
//request.OnBeforeDeserialization = resp => { resp.ContentLength = 761; };
var response = client.Execute<T>(request);
return response.Data;
}
And finally, here is my POCO
public class Location
{
public string BusinessUnit { get; set; }
public string BusinessUnitName { get; set; }
public string LocationId { get; set; }
public string LocationCode { get; set; }
public string LocationName { get; set; }
}
Additionally, the ErrorException and ErrorResponse properties on the response are NULL.
This seems like a very simple case, but I've been running around in circles all day! Thanks.
What is the Content-Type in the response? If not a standard content type like "application/json", etc. then RestSharp won't understand which deserializer to use. If it is in fact a content type not "understood" by RestSharp (you can verify by inspecting the Accept sent in the request), then you can solve this by doing:
client.AddHandler("my_custom_type", new JsonDeserializer());
EDIT:
Ok, sorry, looking at the JSON again, you need something like:
public class LocationResponse
public LocationResult Result { get; set; }
}
public class LocationResult {
public Location Location { get; set; }
}
And then do:
client.Execute<LocationResponse>(request);