Json response to C# Object - c#

I am trying to convert Json Response to C# object. My code is as below.
$ HttpResponseMessage response = client.GetAsync(TARGETURL).Result;
HttpContent content = response.Content;
// ... Check Status Code
Console.WriteLine("Response StatusCode: " + (int)response.StatusCode);
// ... Read the string.
string result = content.ReadAsStringAsync().Result;
Environment myJsonResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<Environment>(result);
Console.Write(myJsonResponse.id);
My Json Object Class is:
public class Environment
{
public string id { get; set; }
public string url { get; set; }
public string name { get; set; }
public string error { get; set; }
public int container_hosts_count { get; set; }
}
Result string is:
"[{\"id\":\"23745576\",\"url\":\"https://cloud.mycloud.com/configurations/23745576\",\"name\":\"mycloud Code Screen - Andy Pande\",\"error\":\"\",\"container_hosts_count\":0}]"
I am getting an error as:
Newtonsoft.Json.JsonSerializationException occurred
HResult=0x80131500
Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Environment' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.

As per the error, you are trying to deserialize a JSON array into a single object. Update your deserialization to:
var myJsonResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<IList<Environment>>(result);

Related

I am trying to deserialize a JSON into a list of objects using .NET 3.1

I have the following Json:
{
"Id":"2727",
"Region":"US",
"Data":[
{
"Title":"Director",
"JobDescription":"Coordinates the department activity",
"Department":"HR"
},
{
"Title":"Programmer",
"JobDescription":"Enterprise software developer",
"Department":"FR"
}
]
}
My format looks like this:
public class Data
{
public string Title { get; set; }
public string JobDescription { get; set; }
public string Department { get; set; }
}
public class Format
{
public string Id { get; set; }
public string Region { get; set; }
public List<Data> Data {get; set;}
}
I have tried to deserialize it like this:
var objects = JsonConvert.DeserializeObject<IEnumerable<Format>>(File.ReadAllText("mockJson.json")).ToList();
I am getting this exception:
An unhandled exception of type
'Newtonsoft.Json.JsonSerializationException' occurred in
Newtonsoft.Json.dll Cannot deserialize the current JSON object (e.g.
{"name":"value"}) into type
'System.Collections.Generic.IEnumerable`1[JSONParsingExample.Format]'
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. Path 'GlobalOrgId', line 2,
position 15.
Just posting this as an answer because I think its worth making it more visible. I assumed the method call was going to have some issues with nesting lists inside a json, but I'm pleased to see it works.
Format format = JsonConvert.DeserializeObject<Format>(File.ReadAllText("mockJson.json"));
I inspected the elements and they all seem to be where they are supposed to be.
Just be careful because JsonConvert.DeserializeObject<T> returns an object of type T, not IEnumerable<T>.
When working with JSON in .NET I'd recommend moving over to the new built in stuff.
https://devblogs.microsoft.com/dotnet/net-core-image-processing/

Accessing JSON object from api in C# [duplicate]

This question already has answers here:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
(5 answers)
Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {"name":"value"}) to deserialize correctly
(6 answers)
Closed 2 years ago.
Im doing a Microsoft Cognitive Services project with langauge detection and text translation.
Im receiving Json from the Microsoft Api, and i want to access it as an object.
I've tried a few different things, including JsonConvert.DeserializeObject, and mapping it to my own objects. (Example below)
// Send the request and get response.
HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
// Read response as a string.
if (response.ReasonPhrase == "OK")
{
//string result = await response.Content.ReadAsStringAsync();
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(result);
}
// The response:
[{
"detectedLanguage":
{
"language":"fi",
"score":1.0
},
"translations":
[
{"text":"This is a test, I hope it works. The text is in Finnish.","to":"en"},
{"text":"Dette er en test, jeg håber det virker. Teksten er på finsk.","to":"da"}
]
}]
// I found an online tool to generate the appropriate classes for mapping
public class DetectedLanguage
{
[JsonPropertyName("language")]
public string Language { get; set; }
[JsonPropertyName("score")]
public double Score { get; set; }
}
public class Translation
{
[JsonPropertyName("text")]
public string Text { get; set; }
[JsonPropertyName("to")]
public string To { get; set; }
}
public class MyArray
{
[JsonPropertyName("detectedLanguage")]
public DetectedLanguage DetectedLanguage { get; set; }
[JsonPropertyName("translations")]
public List<Translation> Translations { get; set; }
}
public class Root
{
[JsonPropertyName("MyArray")]
public List<MyArray> MyArray { get; set; }
}
// The Error im getting
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'textananlytics_test.Root' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.'
You can change
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(result);
to
List<MyArray> list = JsonConvert.DeserializeObject<List<MyArray>>(result);
Root myDeserializedClass=new Root{MyArray=list};
In your case, JSON must has next structure:
{
"MyArray": [
{ /* MyArray jobject */ },
{ /* MyArray jobject */ },
...
]
}
So Yiyi You wrote correct processing

C# - Cannot deserialize the current JSON array

I have this code:
string json2 = vc.Request(model.uri + "?fields=uri,transcode.status", "GET");
var deserial = JsonConvert.DeserializeObject<Dictionary<string, object>>(json2);
var transcode = deserial["transcode"];
var serial = JsonConvert.SerializeObject(transcode);
var deserial2 = JsonConvert.DeserializeObject<Dictionary<string, object>>(serial);
var upstatus = deserial2["status"].ToString();
The json I get from the server is:
{
"uri": "/videos/262240241",
"transcode": {
"status": "in_progress"
}
}
When running it on VS2017, it works.
But on VS2010 I get the following error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'System.Collections.Generic.Dictionary`2[System.String,System.Object]'
because the type requires a JSON object (e.g. {"name":"value"}) to
deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array.
JsonArrayAttribute can also be added to the type to force it to
deserialize from a JSON array.
Path '', line 1, position 1.
I am using Newtonsoft.Json.
Any idea?
Your received json data is not a Dictionary<string, object>, it is a object
public class Transcode
{
public string status { get; set; }
}
public class VModel
{
public string uri { get; set; }
public Transcode transcode { get; set; }
}
You can use this object:
var deserial = JsonConvert.DeserializeObject<VModel>(json2);
instead of:
var deserial = JsonConvert.DeserializeObject<Dictionary<string, object>>(json2);
The best answer was deleted for some reason, so i'll post it:
var deserial = JsonConvert.DeserializeObject<dynamic>(json2);
string upstatus = string.Empty;
upstatus = deserial.transcode.status.ToString();
If your model is not well defined or it is dynamic, then use:
var deserial = JsonConvert.DeserializeObject<dynamic>(json2);
or you can try to use:
JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json2);

Deserialization using newtonsoft

I'm new to C# and i want to deserialize the JSON file into the API using NewtonSoft but it lead me to this error
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'API.JSonConfiguration.exampleLibrary' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
"To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.'"
string url = #"http://180.232.67.229/api/jfiller";
string Data = new WebClient().DownloadString(url
exampleLibrary json = JsonConvert.DeserializeObject<exampleLibrary>(Data);
MessageBox.Show(json.filler_id);
exampleLibrary Class:
public string filler_id { get; set; }
public string filler_title { get; set; }
public string filler_type { get; set; }
JSON
[
{
"filler_id":"1",
"filler_title":"Star118 E-CarDemo",
"filler_type":"1",
"filler_file":"Star118CarTeaser‌​1.mp4",
"filler_durat‌​ion":"83",
"created_a‌​t":"2017-06-10 09:08:41",
"updated":"2017-06-10 09:08:41","status":"0"
},
{
"filler_id":"2",
"filler_title":"Sta‌​r118",
"filler_type":‌​"2",
"filler_file":"S‌​tar118Solar1.PNG",
"f‌​iller_duration":"10"‌​,
"created_at":"2017-‌​06-10 09:09:26",
"updated":"2017-06-10 09:09:26","status":"0"
}
]
Try
JsonConvert.DeserializeObject<IEnumerable<exampleLibrary>>(Data);
You have an array of data but don't specify it in your JsonConvert or in your exampleLibrary Class(That I can see from your posted code).

JSON object deserialize to c# object - OpenTSDB

I am dealing with JSON for the first time and getting data from OpenTSDB. I've created a c# class to deserialize the JSON to but I am getting the error 'Cannot deserialize the current JSON array' as described below.
My c# code to get JSON:
var request = WebRequest.Create("http://localhost:4242/api/query?start=2013/08/21-12:00:00&end=2013/08/22-12:00:00&m=sum:tcollector.collector.lines_sent&o=&yrange=%5B0:%5D&wxh=924x773");
request.ContentType = "application/json; charset=utf-8";
string text;
try
{
var response = (HttpWebResponse) request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
uxResponse.Text = text;
OpenTSDBResponse myObject = (OpenTSDBResponse)Newtonsoft.Json.JsonConvert.DeserializeObject(text, typeof(OpenTSDBResponse));
var variable = Newtonsoft.Json.JsonConvert.DeserializeObject(text);
//var tester = myObject;
}
catch (Exception ex)
{
uxResponse.Text = GetFullExceptionMessage(ex);
}
The JSON I am receiving from the above code (i.e. the 'text' variable):
[{
"metric":"tcollector.collector.lines_sent",
"tags":
{
"host":"ubuntu1"
},
"aggregateTags":["collector"],
"dps":
{
"1377050434":1271779.0,
"1377050494":1272073.0,
"1377050554":1272502.0,
"1377050614":1273632.0,
"1377050674":1273867.0
}
}]
My c# classes
internal class OpenTSDBResponse
{
[JsonProperty("metric")]
public string Metric { get; set; }
[JsonProperty("tags")]
public Tags Tags { get; set; }
[JsonProperty("aggregateTags")]
public string[] AggregateTags { get; set; }
[JsonProperty("dps")]
public List<TimeValue> TimeValues { get; set; }
}
internal class Tags
{
[JsonProperty("host")]
public string Host { get; set; }
}
internal class TimeValue
{
[JsonProperty("Time")]
public double Time { get; set; }
[JsonProperty("Value")]
public double Value { get; set; }
}
The error when deserializing object:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'MyNamespace.OpenTSDBResponse' because the type requires a JSON
object (e.g. {"name":"value"}) to deserialize correctly.To fix this
error either change the JSON to a JSON object (e.g. {"name":"value"})
or change the deserialized type to an array or a type that implements
a collection interface (e.g. ICollection, IList) like List that can
be deserialized from a JSON array. JsonArrayAttribute can also be
added to the type to force it to deserialize from a JSON array.Path
'', line 1, position 1.
Additional Information
I used the codeproject deserialize JSON project to create my basic classes, but it created a new c# property for each '"1377050434":1271779.0,' so I updated to use my TimeValue class. http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-C
Question:
How do I get this into an appropriate c# class structure?
Additional Information in response to users comments below:
bjaminn's comment:
I believe the JSON you are receiving is an array. The exception is trying to say you are converting an object[] to OpenTSDBResponse when you really want OpenTSDBResponse[]. Another way to debug this would be to look at the variable variable and see what type it is in the debugger. Of course the line that throws the exception would need to be commented out.
Outcome: I modified the deserialize like this
OpenTSDBResponse[] myObject = (OpenTSDBResponse[])Newtonsoft.Json.JsonConvert.DeserializeObject(text, typeof(OpenTSDBResponse[]));
but received the following error when I ran it:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[MyNamespace.OpenTSDBResponseJsonTypes.TimeValue]' 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.Path '[0].dps.1377050434', line 1, position 121.
Additional Notes on working solution for other new to JSON
I have added another property to my class for the Dictionary as it's really "unix-time-stamp-data","Value". This allows me to work in c# with datetime/values. There may be a better way for casting but this works an doesn't cause any noticeable performance issues for my scenario.
[JsonProperty("dps")]
public Dictionary<string, double> TimeValues { get; set; }
public List<TimeValue> DataPoints
{
get
{
List<TimeValue> times = new List<TimeValue>();
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
foreach (var item in TimeValues)
{
times.Add(new TimeValue
{
Time = dtDateTime.AddSeconds(double.Parse(item.Key)).ToLocalTime(),
Value = item.Value
});
}
return times;
}
}
I believe the JSON you are receiving is an array. The exception is trying to say you are converting an object[] to OpenTSDBResponse when you really want OpenTSDBResponse[].
Another way to debug this would be to look at the variable variable and see what type it is in the debugger. Of course the line that throws the exception would need to be commented out.
Tackling new error
It looks like DPS is not a proper JSON array. You could parse it to a dictionary since it looks like the keys will be different in each JSON call.
JSON convert dictionary to a list of key value pairs
New class:
internal class OpenTSDBResponse
{
[JsonProperty("metric")]
public string Metric { get; set; }
[JsonProperty("tags")]
public Tags Tags { get; set; }
[JsonProperty("aggregateTags")]
public string[] AggregateTags { get; set; }
[JsonProperty("dps")]
public Dictionary<string,double> TimeValues { get; set; }
}
You can such so modify your Json Data and your C# Code,for example
[{
"metric":"tcollector.collector.lines_sent",
"tags":
{
"host":"ubuntu1"
},
"aggregateTags":["collector"],
"dps":
[
{"Time":"1377050434","Value":1271779.0},
{"Time":"1377050554","Value":1272502.0}
]
}]
c# Code:
You provide the data is an Array,so when you deserialize the string,you must such so use generic format of deserializeobject
object obj=Newtonsoft.Json.JsonConvert.DeserializeObject<List<OpenTSDBResponse>>(json.ToString());

Categories

Resources