im having trouble translating a json response from google's apis to DataContract classes. Specifically when trying to translate an int array from JSON to an int array in the DataContract.
Heres what I have done so far.
Heres the JSON response.
{
"kind": "youtubeAnalytics#resultTable",
"columnHeaders": [
{
"name": "views",
"columnType": "METRIC",
"dataType": "INTEGER"
},
{
"name": "likes",
"columnType": "METRIC",
"dataType": "INTEGER"
},
{
"name": "dislikes",
"columnType": "METRIC",
"dataType": "INTEGER"
}
],
"rows": [
[
2162435,
871,
907
]
]
}
And heres my Data Contract classes
[DataContract]
public class AnalyticsData
{
[DataMember(Name = "kind")]
public string Kind { get; set; }
[DataMember(Name = "columnHeaders")]
public ColumnRows[] ColumnHeaders { get; set; }
[DataMember(Name = "rows")]
public int[][] rows { get; set; } //<--------
}
[DataContract]
public class ColumnRows
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "columnType")]
public string ColumnType { get; set; }
[DataMember(Name = "dataType")]
public string DataType { get; set; }
}
The problem I am having is translating the 'rows' element from the JSON doc into DataContract variables, as as shown in the AnalyticsData class in the int array 'rows'.
The error I get when debugging is
System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type StudioWP8.AnalyticsData. Input string was not in a correct format. ---> System.FormatException: Input string was not in a correct format.
Use jsonconvert and it will be ok
[TestMethod]
public void test()
{
string json =
"{ \"kind\": \"youtubeAnalytics#resultTable\", \"columnHeaders\": [ { \"name\":\"views\", \"columnType\": \"METRIC\", \"dataType\": \"INTEGER\" }, { \"name\": \"likes\", \"columnType\": \"METRIC\", \"dataType\": \"INTEGER\" }, { \"name\": \"dislikes\", \"columnType\": \"METRIC\", \"dataType\":\"INTEGER\" } ], \"rows\": [ [ 2162435, 871,907 ] ]}";
AnalyticsData d = JsonConvert.DeserializeObject<AnalyticsData>(json);
}
Related
I have this JSON:
[
{
"Attributes": [
{
"Key": "Name",
"Value": {
"Value": "Acc 1",
"Values": [
"Acc 1"
]
}
},
{
"Key": "Id",
"Value": {
"Value": "1",
"Values": [
"1"
]
}
}
],
"Name": "account",
"Id": "1"
},
{
"Attributes": [
{
"Key": "Name",
"Value": {
"Value": "Acc 2",
"Values": [
"Acc 2"
]
}
},
{
"Key": "Id",
"Value": {
"Value": "2",
"Values": [
"2"
]
}
}
],
"Name": "account",
"Id": "2"
},
{
"Attributes": [
{
"Key": "Name",
"Value": {
"Value": "Acc 3",
"Values": [
"Acc 3"
]
}
},
{
"Key": "Id",
"Value": {
"Value": "3",
"Values": [
"3"
]
}
}
],
"Name": "account",
"Id": "2"
}
]
And I have these classes:
public class RetrieveMultipleResponse
{
public List<Attribute> Attributes { get; set; }
public string Name { get; set; }
public string Id { get; set; }
}
public class Value
{
[JsonProperty("Value")]
public string value { get; set; }
public List<string> Values { get; set; }
}
public class Attribute
{
public string Key { get; set; }
public Value Value { get; set; }
}
I am trying to deserialize the above JSON using the code below:
var objResponse1 = JsonConvert.DeserializeObject<RetrieveMultipleResponse>(JsonStr);
but I am getting this error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'test.Model.RetrieveMultipleResponse' 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.
Your json string is wrapped within square brackets ([]), hence it is interpreted as array instead of single RetrieveMultipleResponse object. Therefore, you need to deserialize it to type collection of RetrieveMultipleResponse, for example :
var objResponse1 =
JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);
If one wants to support Generics (in an extension method) this is the pattern...
public static List<T> Deserialize<T>(this string SerializedJSONString)
{
var stuff = JsonConvert.DeserializeObject<List<T>>(SerializedJSONString);
return stuff;
}
It is used like this:
var rc = new MyHttpClient(URL);
//This response is the JSON Array (see posts above)
var response = rc.SendRequest();
var data = response.Deserialize<MyClassType>();
MyClassType looks like this (must match name value pairs of JSON array)
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class MyClassType
{
[JsonProperty(PropertyName = "Id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "Description")]
public string Description { get; set; }
[JsonProperty(PropertyName = "Manager")]
public string Manager { get; set; }
[JsonProperty(PropertyName = "LastUpdate")]
public DateTime LastUpdate { get; set; }
}
Use NUGET to download Newtonsoft.Json add a reference where needed...
using Newtonsoft.Json;
Can't add a comment to the solution but that didn't work for me. The solution that worked for me was to use:
var des = (MyClass)Newtonsoft.Json.JsonConvert.DeserializeObject(response, typeof(MyClass));
return des.data.Count.ToString();
Deserializing JSON array into strongly typed .NET object
Use this, FrontData is JSON string:
var objResponse1 = JsonConvert.DeserializeObject<List<DataTransfer>>(FrontData);
and extract list:
var a = objResponse1[0];
var b = a.CustomerData;
To extract the first element (Key) try this method and it will be the same for the others :
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.GetAsync("Your URL"))
{
var apiResponse = await response.Content.ReadAsStringAsync();
var list = JObject.Parse(apiResponse)["Attributes"].Select(el => new { Key= (string)el["Key"] }).ToList();
var Keys= list.Select(p => p.Key).ToList();
}
}
var objResponse1 =
JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);
worked!
I have following json:
{
"Australia": {
"count": 2,
"records": {
"File1.ppt": {
"id": "123456789"
},
"File2.doc": {
"id": "987654321"
}
}
},
"PDFs.zip": {
"count": 0,
"records": {}
},
"Peru": {
"count": 2,
"records": {
"File3.PPT": {
"id": "897456123"
},
"File4.PPT": {
"id": "123546789"
}
}
},
"total count": 4
}
and to deserialize the above json I have defined some classes so that I can use these classes while deserializing my json into objects and below are the classes:
namespace GEO_Batch_Creation
{
[DataContract]
class BhpIdJson
{
[DataMember(Name = "objects")]
public Dictionary<string, Country[]> Countries { get; set; }
[DataMember(Name = "total count")]
public int TotalCount { get; set; }
}
[DataContract]
class Country
{
[DataMember(Name = "count")]
public int Count { get; set; }
[DataMember(Name = "records")]
public Dictionary<string, Record> Records { get; set; }
}
[DataContract]
class Record
{
[DataMember(Name = "filename")]
public string FileName { get; set; }
[DataMember(Name = "id")]
public Dictionary<string, string> BhpId { get; set; }
}
}
But when I use following code to deserialize the json I am getting only total count.
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
// Deserialization from JSON
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(BhpIdJson));
BhpIdJson bsObj2 = (BhpIdJson)deserializer.ReadObject(ms);
}
Please suggest me where I am doing mistake.
I don't think that this JSON is in correct format. I don't know if you got this from somewhere or made for yourself, but if the last one I recommend you to change the structure.
Even in C# you cant realy create a class that has the objects and the count of the object in the same List or Array etc.
Based on your class your JSON yhould look like this:
{
"objects": [
{
"name": "Australia",
"count": 2,
"records": [
{
"fileName": "File1.ppt",
"id": "123456789"
},
{
"fileName": "File2.doc",
"id": "987654321"
}
]
}
],
"total count": 4
}
As you can see you have to add Name or something to your Country class. I hope it helped.
Edit:
You can create a list like I mentioned above but it's not a good practice I think.
I have a two simple PHP class
class Order{
public $orderNo;
public $lines = array();
public $paid = false;
public function addLine(OrderLine $line) {
$this->lines[] = $line;
}
public function setPaid($paid = true) {
$this->paid = true;
}
}
class OrderLine{
public function __construct($item, $amount){
$this->item = $item;
$this->amount = $amount;
}
public $item;
public $amount;
public $options;
}
Serialize object uses https://github.com/mindplay-dk/jsonfreeze
...
$json = new JsonSerializer;
$data = $json->serialize($order);
Have output:
{
"#type": "Order",
"orderNo": 123,
"lines": [{
"#type": "OrderLine",
"item": "milk \"fuzz\"",
"amount": 3,
"options": null
},{
"#type": "OrderLine",
"item": "cookies",
"amount": 7,
"options": {
"#type": "#hash",
"flavor": "chocolate",
"weight": "1\/2 lb"
}
}],
"paid": true
}
Send the string XMLRPC in VB.NET
As using Newtonsoft JSON get a live object?
As well as how to create a compatible format by analogy with the json string of living VB.net OR C# object?
Here's something you could start with. You create some classes with properties which represent the JSON Format (untested code, just as idea):
public class MyData
{
[JsonProperty("#type")]
public string Type { get; set; }
[JsonProperty("#orderNo")]
public int OrderNo { get; set;
[JsonProperty("paid")]
public bool Paid { get; set; }
[JsonProperty("lines")]
public List<MyDataLine> Lines { get; set; }
}
public class MyDataLines
{
[JsonProperty("#type")]
public string Type { get; set; }
[JsonProperty("options")]
public MyDataLinesOptions Options { get; set; }
// ... more
}
public class MyDataLinesOptions
{
// ... more
}
Then you can serialize and deserialize the the data like this:
string json = "the json data you received";
MyData myData = JsonConvert.DeserializeObject<MyData>(json);
// ...
json = JsonConvert.SerializeObject(myData);
"#type": "Order"
and
"#type": "OrderLine",
this is not a property, this is an indication of the type of the object
I just got my json response as a string.My json is given below,
"code": 0,
"message": "success",
"students": {
"details":{
"hjeke": {
"id": "257633000000070001",
"name": "hjeke",
"percentage": 36,
"type": "Good",
},
"Second": {
"id": "257633000000073001",
"name": "Second",
"percentage": 4,
"type": "bad",
}
}
}
Like hjeke and Second there are many key value pairs,how can i deserialize my json using Newtonsoft.json
Try to understand my solution in your previous question
How to deserialize json data in windows phone?
Your first JSON in that question was good and simple to use.
JSON, where field names are unique not convinient to deserialize. So, you got problems such as public class Hjeke and public class Second for each instance, when you use code generator.
Use JSON-structure with list of students:
"code": 0,
"message": "success",
"students": [
{
"id": "257633000000070001",
"name": "hjeke",
"percentage": 36,
"type": "Good",
},
{
"id": "257633000000073001",
"name": "Second",
"percentage": 4,
"type": "bad",
}]
is good and flexible structure. Using this, you don't need to parse not obvious fields like
"details":{
"hjeke": {
and so on.
And work with them using classes, from my previous answer. The main idea - you need list of objects. public List<StudentDetails> students. Then, all students objects deserialized in List, which is easy to use.
As everybody mentioned your json seems to be very unflexible, huh.
You can extract the data you are interested in.
So this is your model:
public class StudentDetails
{
public string id { get; set; }
public string name { get; set; }
public int percentage { get; set; }
public string type { get; set; }
}
And this is how you can extract it:
var jsonObj = JObject.Parse(str);
// get JSON result objects into a list
var results = jsonObj["students"]["details"].Children().Values();
// serialize JSON results into .NET objects
var details = new List<StudentDetails>();
foreach (JToken result in results)
{
var st = result.ToString();
var searchResult = JsonConvert.DeserializeObject<StudentDetails>(st);
details.Add(searchResult);
}
I'm using a newtonsoft.json library here.
Your Response string has some mistakes man, its not a valid json
just small modification to be done as below:
{
"code": 0,
"message": "success",
"students": {
"details": {
"hjeke": {
"id": "257633000000070001",
"name": "hjeke",
"percentage": 36,
"type": "Good"
},
"Second": {
"id": "257633000000073001",
"name": "Second",
"percentage": 4,
"type": "bad"
}
}
}
}
you can make out the difference
Now Follow these steps:
1.Go to this link Json to C#
2.place your Json string there and generate C# class object
3.Now create this class in your solution
4.Now deserialize As below
var DeserialisedObject = JsonConvert.DeserializeObject<Your Class>(YourJsonString);
First, create the classes:
public class Hjeke
{
public string id { get; set; }
public string name { get; set; }
public int percentage { get; set; }
public string type { get; set; }
}
public class Second
{
public string id { get; set; }
public string name { get; set; }
public int percentage { get; set; }
public string type { get; set; }
}
public class Details
{
public List<Hjeke> hjeke { get; set; }
public List<Second> Second { get; set; }
}
public class Students
{
public List<Details> details { get; set; }
}
public class RootObject
{
public int code { get; set; }
public string message { get; set; }
public List<Students> students { get; set; }
}
After that, use JSON.NET to deserialize:
var deserialized = JsonConvert.DeserializeObject<Class1>(YourStringHere);
Do you have any influence over the json response? Details should probably be a JSONArray in this case, not an object with a varying amount of properties, since I assume that's what you mean is the issue here.
I have a json data when i'm trying to parse it returns error incorrect syntax please help me found the syntax error.
[{"isData":"Yes","Details":"[{"Id":"70","Name":"Test","FileName":"Uploaded","FileFormat":".mp4","FileType":"Video","FileDuration":"00:30:00 ","StartTime":"/Date(1372617000000)/","EndTime":"/Date(1372681771000)/","File":"2562013172331815635077778118152815.mp4"}]"}]
And this is the class that is used to serialize data, i am using javascript serializer
public enum Data
{
Yes,
No
}
public class MessageResponse()
{
public string isData { get; set; }
public string Details { get; set; }
}
List<MessageResponse> response = new List<MessageResponse>();
string strJson="[{"Id":"70","Name":"Test","FileName":"Uploaded","FileFormat":".mp4","FileType":"Video","FileDuration":"00:30:00 ","StartTime":"/Date(1372617000000)/","EndTime":"/Date(1372681771000)/","File":"2562013172331815635077778118152815.mp4"}]";
var newData = new MessageResponse
{
isData = Data.Yes.ToString(),
Details = strJson
};
response.Add(newData);
var jsonSerialiser1 = new JavaScriptSerializer();
string result = jsonSerialiser1.Serialize(response);
That's invalid JSON. The Details property is incorrectly formatted. You should remove the quotes around the value. It should be like this:
[
{
"isData": "Yes",
"Details": [
{
"Id": "70",
"Name": "Test",
"FileName": "Uploaded",
"FileFormat": ".mp4",
"FileType": "Video",
"FileDuration": "00:30:00 ",
"StartTime": "/Date(1372617000000)/",
"EndTime": "/Date(1372681771000)/",
"File": "2562013172331815635077778118152815.mp4"
}
]
}
]
or if you want Details to be a string property (representing JSON), which is kinda lame, you should properly escape the double quotes:
[
{
"isData": "Yes",
"Details": "[{\"Id\":\"70\",\"Name\":\"Test\",\"FileName\":\"Uploaded\",\"FileFormat\":\".mp4\",\"FileType\":\"Video\",\"FileDuration\":\"00: 30: 00\",\"StartTime\":\"/Date(1372617000000)/\",\"EndTime\":\"/Date(1372681771000)/\",\"File\":\"2562013172331815635077778118152815.mp4\"}]"
}
]
This structure you will be able to map to your current object model. But I would recommend you using the first approach.
Remove the " from the details data:
[{
"isData":"Yes",
"Details":
[{
"Id":"70",
"Name":"Test",
"FileName":"Uploaded",
"FileFormat":".mp4",
"FileType":"Video",
"FileDuration":"00:30:00",
"StartTime":"/Date(1372617000000)/",
"EndTime":"/Date(1372681771000)/",
"File":"2562013172331815635077778118152815.mp4"
}]
}]
Details should be of type class (i.e. user defined class) and it should hold all the properties.
public class Details
{ public int Id {get; set;} ... }
Firstly your json is invalid.
It should not have the " before and after the [ ]
[
{
"isData": "Yes",
"Details": [
{
"Id": "70",
"Name": "Test",
"FileName": "Uploaded",
"FileFormat": ".mp4",
"FileType": "Video",
"FileDuration": "00: 30: 00",
"StartTime": "/Date(1372617000000)/",
"EndTime": "/Date(1372681771000)/",
"File": "2562013172331815635077778118152815.mp4"
}
]
}
]
Secondly, your class could be improved to be:
public class MessageResponse
{
public string isData { get; set; }
public Details Details { get; set; }
}
public class Details
{
public int Id { get; set; }
public string Name { get; set; }
public string FileName { get; set; }
public string FileFormat { get; set; }
public string FileType { get; set; }
public string FileDuration { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public string File { get; set; }
}
You would probably want to set up the correct data types though for things like Start Time etc...