So I have a problem where after Deserialization my JSON converts to an object (There no other way for this). In my object there is another object called "Content".
This objects holds an array but since this also needs to be converted to an object it comes out as this:
object Content = {[
{
"geofence_id": 44896,
"name": "WAAAAAAAAAAAAA"
},
{
"geofence_id": 44920,
"name": "Work"
}
]}
(For this is also no other way).
Now I wish to know how to convert this object to an object array.
I tried:
GeofenceResponse[] arr = Content as GeofenceResponse[];
Where content.Content is the object shown in the top snippet and GeofenceResponse[] is the objectarray.
But this resulted in arr being null.
A GeofenceResponse looks like this:
class GeofenceResponse : Response
{
public int Geofence_id { get; set; }
public string Name { get; set; }
}
A response is just:
class Response
{
}
Since I have multiple different ones.
But I get multiple of them in the Contect object.
Your JSON seems invalid {[...]} is not valid per http://www.json.org/
BTW valid object wrapping of array is {"content":[...]}
You should not wrap the array into object but deserialize the array directly:
string json = #"[
{
'Name': 'Product 1',
'ExpiryDate': '2000-12-29T00:00Z',
'Price': 99.95,
'Sizes': null
},
{
'Name': 'Product 2',
'ExpiryDate': '2009-07-31T00:00Z',
'Price': 12.50,
'Sizes': null
}
]";
List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
Sample taken from https://www.newtonsoft.com/json/help/html/SerializingCollections.htm
Managed to find the answer myself, all I had to do was:
GeofenceResponse[] arr = JsonConvert.DeserializeObject<GeofenceResponse[]>(content.Content.ToString(), jsonSettings);
This resulted in a perfectly filled array of GeofenceResponses
Related
I have some Json content that contains an array, where each item contains an array of objects. I'm searching for a way to convert this into a list of objects. It is only the object with id and biCode is what I'm after, their parent is of no importance for me
I tried the https://json2csharp.com/ website, but according to the output I need to create a Class for each parent object ("UselessText1", "UselessText2", etc) and they just contain id and biCode. I tried to use it, but (as I would have guessed) it didn't work
It threw this Exception: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Root]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
This is the json:
{
"UselessText1": [],
"UselessText2": [
{
"id": 2,
"biCode": "Something useful"
}
],
"UselessText3": [
{
"id": 3,
"biCode": "Something useful"
},
{
"id": 4,
"biCode": "Something useful"
}
]}
Any idea how to deserialize this? Any Google result I found didn't show a situation like mine. I probably didn't know exactly what to search for
try this
var json=...your json string
var deseializedJson = JsonConvert.DeserializeObject< Dictionary<string,UselessText[]>>(json);
var output = JsonConvert.SerializeObject(deseializedJson);
public class UselessText
{
public int id { get; set; }
public string biCode { get; set; }
}
output
{"UselessText1":[],
"UselessText2":[{"id":2,"biCode":"Something useful"}],
"UselessText3":[{"id":3,"biCode":"Something useful"},{"id":4,"biCode":"Something useful"}]}
Your Json example is a little bit weird. It looks like you have an object that contains multiple properties of the same type.
Something that should work for this exact Json would be:
public class MyModel{
public IEnumerable<MyEntity> UselessText1;
public IEnumerable<MyEntity> UselessText2;
public IEnumerable<MyEntity> UselessText3;
}
public class MyEntity{
public int Id;
public string BiCode;
}
I have the following json that contains an unnamed array and other named properties. I'd like to know how to deserialize it to a class, using Newtonsoft.Json.
{
"message": "success",
[
{
"timestamp": 1509723862,
"tid": 84823616,
"price": "7344.7",
"amount": "0.36108123",
"exchange": "bitfinex",
"type": "sell"
},
{
...
}
]
}
I know I could deserialize the array using
serializer.DeserializeObject< List < Response > >(serializedObject), but as the json contains other properties, it is not a json-array string.
Is there any configuration that I could use to tell Newtonsoft.Json to deserialize the array into a List, and the 'message' property to a string, in the class bellow:
public class Response
{
public string Message {get;set;}
public List<ResponseItem> ResponseItems {get;set;}
}
public class ResponseItem {
string timestamp {get;set;}
(...)
}
A JSON can't have both an unnamed array and a named value on the same level. The JSON is invalid. Either everything is keyed, or it's an unkeyed array. Can't have both.
I think it's not a good idea to concate the two Json's.
Use your own Deserializer and pass your two Json's:
public static class ResponseDeserializer
{
public static Response Deserialize(string psMessage, string psResponeItems)
{
dynamic loMessage = JsonConvert.DeserializeObject(psMessage);
return new Response()
{
Message = loMessage.message,
ResponseItems = JsonConvert.DeserializeObject<List<ResponseItem>>(psResponeItems)
};
}
}
And use it:
string lsMessage = "{\"message\":\"Unknown symbol\"}";
string lsResponseItems = "[{\"timestamp\":1509726632,\"tid\":84840931,\"price\":\"7298.8\",\"amount\":\"0.0044733\",\"exchange\":\"bitfinex\",\"type\":\"sell\"},{\"timestamp\":1509726630,\"tid\":84840921,\"price\":\"7297.3\",\"amount\":\"0.11550649\",\"exchange\":\"bitfinex\",\"type\":\"sell\"},{\"timestamp\":1509726630,\"tid\":84840911,\"price\":\"7297.2\",\"amount\":\"0.0214149\",\"exchange\":\"bitfinex\",\"type\":\"buy\"},{\"timestamp\":1509726629,\"tid\":84840909,\"price\":\"7297.2\",\"amount\":\"0.41004892\",\"exchange\":\"bitfinex\",\"type\":\"buy\"}]";
var loResponse = ResponseDeserializer.Deserialize(lsMessage, lsResponseItems);
Console.WriteLine(loResponse.Message);
I have a JSON string below:
{
"data": [
{
//data for first
},
{
//data for second
},
{
//data for third
},
]
}
From this JSON string, I would like to retrieve the number of objects within the "data" element, which in this case, would be 3.
What would be the best approach to accomplish this? I used the .Length property, but that returned a number that I did not expect.
I am using C#.
Since it's a string in C# you need to parse it into something you can use first. Here's a simple way using framework classes.
//obj is your JSON string
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
Dictionary<string,object> csObj =
serializer.Deserialize<Dictionary<string,object>>(obj);
int length = ((ArrayList)csObj["data"]).Count;
When given a generic data structure, JavaScriptSerializer turns arrays into ArrayLists.
Here's an example using Newtonsoft.Json (Json.NET) which is available as a NuGet package.
Usage:
var jsonString = #"{
""data"": [
{
Name: ""Mike"", Age: 30
},
{
Name: ""John"", Age: 42
},
{
Name: ""Tom"", Age: 44
}
]
}";
var example = JsonConvert.DeserializeObject<Example>(jsonString);
// example.Data.Length == 3 at this point
Classes
class Example
{
public Person[] Data { get; set; }
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
You need to first deserialize your json string to get objects. The below post has a couple examples. After you deserialize you should have a collection of your data objects in c# (not a string). From there you should be able to call collection.Count or array.Length depending on what collection type you are using.
C# automatic property deserialization of JSON
Finding some difficulty in sourcing information in trying to deserialize JSON in C#.
I have results from Google custom search returned in JSON format. I just want to check through my steps and establish the order in trying to deserialize it. Is this right?
I need to create classes to match
the JSON format. Kind of like a
creating schema file.
Use the JavaScriptSerializer() class and
deserialize method to extract the
relevant bits.
One of the issues I think I am going to run into is that I don't require all of the data returned but only the html links. How can I achieve that?
UPDATE
I have updated my question with the following JSON snippet and C# code. I want to output the string 'links' to console but it doesn't seem to be working. I think I am defining my classes wrongly?
JSON from Google Custom Search
handleResponse({
"kind": "customsearch#search",
"url": {
"type": "application/json",
"template": "https://www.googleapis.com/customsearch/v1?q\u003d{searchTerms}&num\u003d{count?}&start\u003d{startIndex?}&hr\u003d{language?}&safe\u003d{safe?}&cx\u003d{cx?}&cref\u003d{cref?}&sort\u003d{sort?}&alt\u003djson"
},
"queries": {
"nextPage": [
{
"title": "Google Custom Search - lectures",
"totalResults": 9590000,
"searchTerms": "lectures",
"count": 1,
"startIndex": 2,
"inputEncoding": "utf8",
"outputEncoding": "utf8",
"cx": "017576662512468239146:omuauf_lfve"
}
],
"request": [
{
"title": "Google Custom Search - lectures",
"totalResults": 9590000,
"searchTerms": "lectures",
"count": 1,
"startIndex": 1,
"inputEncoding": "utf8",
"outputEncoding": "utf8",
"cx": "017576662512468239146:omuauf_lfve"
}
]
},
"context": {
"title": "Curriculum",
"facets": [
[
{
"label": "lectures",
"anchor": "Lectures"
}
],
[
{
"label": "assignments",
"anchor": "Assignments"
}
],
[
{
"label": "reference",
"anchor": "Reference"
}
]
]
},
"items": [
{
"kind": "customsearch#result",
"title": "EE364a: Lecture Videos",
"htmlTitle": "EE364a: \u003cb\u003eLecture\u003c/b\u003e Videos",
"link": "http://www.stanford.edu/class/ee364a/videos.html",
"displayLink": "www.stanford.edu",
"snippet": "Apr 7, 2010 ... Course materials. Lecture slides · Lecture videos (2008) · Review sessions. Assignments. Homework · Reading. Exams. Final exam ...",
"htmlSnippet": "Apr 7, 2010 \u003cb\u003e...\u003c/b\u003e Course materials. \u003cb\u003eLecture\u003c/b\u003e slides · \u003cb\u003eLecture\u003c/b\u003e videos (2008) · Review sessions. \u003cbr\u003e Assignments. Homework · Reading. Exams. Final exam \u003cb\u003e...\u003c/b\u003e",
"cacheid": "TxVqFzFZLOsJ"
}
]
}
);
C# Snippet
public class GoogleSearchResults
{
public string link { get; set; }
}
public class Program
{
static void Main(string[] args)
{
//input search term
Console.WriteLine("What is your search query?:");
string searchTerm = Console.ReadLine();
//concantenate the strings using + symbol to make it URL friendly for google
string searchTermFormat = searchTerm.Replace(" ", "+");
//create a new instance of Webclient and use DownloadString method from the Webclient class to extract download html
WebClient client = new WebClient();
string Json = client.DownloadString("https://www.googleapis.com/customsearch/v1?key=My Key&cx=My CX&q=" + searchTermFormat);
//create a new instance of JavaScriptSerializer and deserialise the desired content
JavaScriptSerializer js = new JavaScriptSerializer();
GoogleSearchResults results = js.Deserialize<GoogleSearchResults>(Json);
Console.WriteLine(results);
//Console.WriteLine(htmlDoc);
Console.ReadLine();
}
}
Thanks
I use your #2 approach: deserialize with the JavaScriptSerializer.
This is what I do to deserialize a response from Facebook:
// get the id for the uploaded photo
var jss = new JavaScriptSerializer();
var resource = jss.Deserialize<Facebook.Data.Resource>(responseText);
....where Facebook.Data.Resource is defined like this:
namespace Facebook.Data
{
public class Resource
{
public string id { get; set; }
}
}
The responseText that I am deserializing from looks like this:
{"id":"10150111918987952",
"from":{"name":"Someone",
"id":"782272221"},
"name":"uploaded from Cropper. (at 12\/15\/2010 7:06:41 AM)",
"picture":"http:\/\/photos-f.ak.fbcdn.net\/hphotos-ak-snc4\/hs817.snc4\/69790_101501113333332_782377951_7551951_8193638_s.jpg",
...
But since I have only one property defined in the Resource class, I only deserialize that. Define the fields in your class that you want to deserialize.
It works to use inheritance, of course. You can define your data classes like this:
namespace Facebook.Data
{
public class Resource
{
public string id { get; set; }
}
public class Person : Resource
{
public string name { get; set; }
}
}
...and then you can deserialize a Person object.
EDIT
Ok, given the sample json you provided in the updated question, here's how I wrote the classes to hold the response:
public class GoogleSearchItem
{
public string kind { get; set; }
public string title { get; set; }
public string link { get; set; }
public string displayLink { get; set; }
// and so on... add more properties here if you want
// to deserialize them
}
public class SourceUrl
{
public string type { get; set; }
public string template { get; set; }
}
public class GoogleSearchResults
{
public string kind { get; set; }
public SourceUrl url { get; set; }
public GoogleSearchItem[] items { get; set; }
// and so on... add more properties here if you want to
// deserialize them
}
And here's the C# code to deserialize:
// create a new instance of JavaScriptSerializer
JavaScriptSerializer s1 = new JavaScriptSerializer();
// deserialise the received response
GoogleSearchResults results = s1.Deserialize<GoogleSearchResults>(json);
Console.WriteLine(s1.Serialize(results));
Some comments:
The toplevel class to hold the search result is called GoogleSearchResults.
The first property in the GoogleSearchResults class is kind, corresponding to the first named property in the json object. You had link which isn't going to work, because link is not the name of a top-level property in that json object. There are properties lower in the hierarchy of your json named "link" but JavaScriptSerializer won't pull out those lower level things into the higher level.
The next property in my GoogleSearchResults class is of type SourceUrl. This is because the url property in the json is not a simple string - it is a json object with two properties, each with a string value. So SourceUrl as a class in C# gets two string properties, each with the appropriate name to deserialize one of those named properties.
the next property in the GoogleSearchResults class is called "items" so that it can deserialize the items dictionary from your json. Now items, as the name suggests, is an array in the json, as denoted by the square bracket around its value. This means there can be more than one item, although in your case there is just one item. So this property in C# must be an array (or collection). Each item in the json result is not a simple string, so, once again, as we did with SourceUrl, we need to define a holder class to deserialize the item object: GoogleSearchItem. This class has a bunch of simple string properties. The properties in the C# class could also be of type int or some other type, if that's what the json requires.
finally, when printing out the result, if you just call Console.WriteLine(result) you will see the result of the ToString() method that is implicitly invoked by Console.WriteLine. This will merely print the name of the type, in this case is "GoogleSearchResults", which is not what you want, I think. In order to see what's in the object, you need to serialize it, as I've shown. In the output of that, you will see only the values of things you deserialized. Using the classes I provided, the result will have less information than the original, because I didn't provide properties in the C# class corresponding to some of the json properties, so those weren't deserialized.
You could take a look at Json.NET and its LINQ support to create and query JSON. By crafting a nice LINQ query you will get only the stuff you need (you can select, group by, count, min, max, whatever you like).
http://msdn.microsoft.com/en-us/library/bb412170.aspx
http://msdn.microsoft.com/en-us/library/bb410770.aspx
Pull out the property you need after you have converted the JSON representation to a type in your C# app. I don't think there's a way to extract only one property from the JSON representation before you have converted it (though I am not sure).
{
"person": "david",
"images": {
"usable_sizes": [
[
[150,
41
],
"image1.png"
],
[
[220,
61
],
"image2.png"
],
[
[220,
61
],
"image3.png"
]
],
"uploader": null
}
}
I am using a JavaScriptSerializer in C# to parse some JSON. The above is the string I get back from the webrequest. Calling Deserialize on the string puts the Person in the right place in the object, but I don't know what type to use for the array nested under "images." I am at a complete loss.
here is relevant code:
TopLevelObject topObj = new JavaScriptSerialize().Deserialize<TopLevelObj>(jsonStream);
public TopLevelObject
{
public string person;
public imgStruct images;
}
public class imgStructure
{
public List<string[,][]> available_sizes;
}
but that's not taking. I have tried a variety of other forms for the class, but can't get the deserialize to put the data in without proper keys. I have no ability to change the inbound JSON as I am consuming it from a third party.
This is what I believe your classes should look like:
public class RootObj
{
public string person;
public ImageDataObj images;
}
public class ImageDataObj
{
public object uploader;
public List<List<object>> usable_sizes
}
As you can see the inner list is a list of objects. That is because the list has items of different types: one is a list (numerical data [150, 41]) and the other is a string (image name). I do not think you can strongly type the inner list for that reason.
Maybe it is worth examining on runtime (using the VS debugging tools) the structure of the objects inside the inner list and that could give you an indication of how to map it.
How the usable_images property type does look like if you take it to its detail is:
public List<List<Dictionary<List<int>,string>>> usable_sizes
but that is just a guess.
I would advise going to JSON.org and using one of their pre-built solutions.