Here's how I try to deserialize my json:
new JavaScriptSerializer().Deserialize<Dictionary<int, MyModel>>(myData);
Here's the class:
public class MyModel
{
public Dictionary<int, ItemModel> Translation { get; set; }
public int Id { get; set; }
}
public class ItemModel
{
public string Name { get; set; }
public string ShortDescription { get; set; }
public string LongDescription { get; set; }
}
And here's the json:
"[[],[],{"Translation":{"1":{"Name":"Bla1","ShortDescription":"bla1","LongDescription":"bla1"},"2":{"Name":"BlaUS1","ShortDescription":"BlaUS1","LongDescription":"BlaUS1"}},"Id":"12"},{"Translation":{"1":{"Name":"Bla22","ShortDescription":"bla22","LongDescription":"bla22"},"2":{"Name":"Bla2US2","ShortDescription":"Bla2US2","LongDescription":"Bla2US2"}},"Id":"13"}]"
and I get the error that the type is not supported for deserialization of an array.
Where is my error?
First of all your JSON looks a bit wrong to me. It is and array of 4 elements and 1st two elements are empty arrays but other two objects? I suspect your JSON should be something like that:
"[{"Translation":{"1":{"Name":"Bla1","ShortDescription":"bla1","LongDescription":"bla1"},"2":{"Name":"BlaUS1","ShortDescription":"BlaUS1","LongDescription":"BlaUS1"}},"Id":"12"},{"Translation":{"1":{"Name":"Bla22","ShortDescription":"bla22","LongDescription":"bla22"},"2":{"Name":"Bla2US2","ShortDescription":"Bla2US2","LongDescription":"Bla2US2"}},"Id":"13"}]"
Another issue is that you have Dictionary<int, ItemModel> but for serialization/deserialization you must have key of String or Object type.
Working example (providing that you changed from Dictionary<int, ItemModel> to Dictionary<object, ItemModel>):
string input = "[{\"Translation\":{\"1\":{\"Name\":\"Bla1\",\"ShortDescription\":\"bla1\",\"LongDescription\":\"bla1\"},\"2\":{\"Name\":\"BlaUS1\",\"ShortDescription\":\"BlaUS1\",\"LongDescription\":\"BlaUS1\"}},\"Id\":\"12\"},{\"Translation\":{\"1\":{\"Name\":\"Bla22\",\"ShortDescription\":\"bla22\",\"LongDescription\":\"bla22\"},\"2\":{\"Name\":\"Bla2US2\",\"ShortDescription\":\"Bla2US2\",\"LongDescription\":\"Bla2US2\"}},\"Id\":\"13\"}]";
List<MyModel> myModels = new JavaScriptSerializer().Deserialize<List<MyModel>>(input);
Your string suggests that what you have is a JSON array, eg:- [1,2,3]
but you are trying to deserialize it into a dictionary for which the json representation is akin to
{"1":"Hai","2":"Hello"}
obviously the library is throwing an error. May be why dont you use the following to deserialize the string.
new JavaScriptSerializer().Deserialize<List<MyModel>[]>(myData)
However, to use it you can't have empty arrays in the json, you have to fill them with default values for the properties.
To prove that the above works, try
"[{"Translation":{"1":{"Name":"Bla1","ShortDescription":"bla1","LongDescription":"bla1"},"2": {"Name":"BlaUS1","ShortDescription":"BlaUS1","LongDescription":"BlaUS1"}},"Id":"12"},{"Translation":{"1":{"Name":"Bla22","ShortDescription":"bla22","LongDescription":"bla22"},"2":{"Name":"Bla2US2","ShortDescription":"Bla2US2","LongDescription":"Bla2US2"}},"Id":"13"}]"
with
new JavaScriptSerializer().Deserialize<List<MyModel>>(myData)
Related
I have the following classes:
public class Countries
{
public List<Country> countries { get; set; }
}
public class Country
{
public string countryName { get; set; }
public string region { get; set; }
public string code { get; set; }
}
Which is being read in via a HttpRequest:
But when I try to deserialise the result:
var Mycountries = JsonConvert.DeserializeObject<Countries>(body);
But the Mycountries variable is always null.
Obviously I'm missing something obvious and I wonder if someone could help me out please?
UPDATE
Trying a different approach produces the following:
Looks like you have a serialized array inside a serialized object, which is why the quotation marks are escaped by 3 backslashes. So because it is serialized 2 times (for whatever reason), you have to deserialize it 2 times; kind of like this:
JObject jObject = (JObject) JsonConvert.DeserializeObject(body);
var Mycountries = new Countries();
Mycountries.contries = JsonConvert.DeserializeObject<List<Country>>(jObject.GetValue("Data").ToString());
TL;DR use the JsonProperty attribute
Add it to your Countries class:
[JsonProperty("Data")]
public class Countries
{
public List<Country> countries { get; set; }
}
Why?
When using the JsonConvert.DeserializeObject method to deserialize a JSON string, but the property names in the JSON string do not match the property names of the target object, you should use the JsonProperty attribute to specify the correct names.
I hope that helps!
Try this
Var Mycountries =
JsonSerialize.Deserialize<Countries>(jsonString);
An existing JSON-based web-service returns a fairly messy JSON object, where all the useful data is contained in the elements of an array which is itself the content of a 1-element array. Something like this (I'm anonymising it, hopefully no typos):
{"rows":[[
{"name":"John","time":"2016-03-20 01:00:00","id":"2","code":"1234"},
{"name":"Sam","time":"2016-03-20 01:00:00","id":"24","code":"999"},
{"name":"Paul","time":"2016-03-20 01:00:00","id":"12","code":"6512"}
]]}
Using JSON.net I need to access each of those row sub-elements but I'm not sure how to iterate over this and if I should be deserializing to a concrete type or just reading the raw data from my json object.
The data will be aggregated inside a method so the 'type' of each row is not something that needs to be known outside the method.
rows will always be a 1-element array containing an array of elements as shown.
#Fals's solution should work well, but if you want to do away with the RootObject, you can use Json.Net's LINQ-to-JSON API to parse the JSON and get the data into a simple list of items that is easy to work with.
Assuming you have a class defined for the item data like this:
public class Item
{
public string name { get; set; }
public DateTime time { get; set; }
public string id { get; set; }
public string code { get; set; }
}
Then you can do this to get your list of items:
List<Item> items = JObject.Parse(json)["rows"][0]
.Select(jt => jt.ToObject<Item>())
.ToList();
Fiddle: https://dotnetfiddle.net/FtB3Cu
If you want to avoid declaring any classes at all and instead use an anonymous type, you can change the code to this:
var items = JObject.Parse(json)["rows"][0]
.Select(jt => new
{
name = (string)jt["name"],
time = (DateTime)jt["time"],
id = (string)jt["id"],
code = (string)jt["code"]
})
.ToList();
Fiddle: https://dotnetfiddle.net/0QXUzZ
It's simple, your root object contains a List<List<>>:
Your object should look like:
public class InnerObject
{
public string name { get; set; }
public DateTime time { get; set; }
public string id { get; set; }
public string code { get; set; }
}
public class RootObject
{
public List<List<InnerObject>> rows { get; set; }
}
Then use JSON.NET:
string json = #"{'rows':[[
{'name':'John','time':'2016-03-20 01:00:00','id':'2','code':'1234'},
{'name':'Sam','time':'2016-03-20 01:00:00','id':'24','code':'999'},
{'name':'Paul','time':'2016-03-20 01:00:00','id':'12','code':'6512'}
]]}";
var rootObject = JsonConvert.DeserializeObject<RootObject>(json);
By the way, this site json2csharp can generate the C# class from JSON, makes the life ease :)
EDIT:
You can also use dynamic, and then avoid the parser from the `RootObject:
var rootObject = JsonConvert.DeserializeObject<dynamic>(json);
rootObject.rows[0] <--- should have what you need
I am writing a program to access Mediafire's web API and it's all going well, the only issue remaining is the response text in JSON format that I have difficulty parsing.
With API calls like creating a folder, I get a simple response which can be deserialized into a Dictionary<string,Dictionary<string,string>> and searched for values:
{"response":
{
"action":"folder\/create.php",
"name":"blargh",
"folder_key":"mmttuu769djo0",
"result":"Success",
"current_api_version":"2.14"
}
}
I would use it like this:
Dictionary<string,string> json = DeserializeJSON(text)["response"];
//DeserializeJSON is a method to shorten:
//JsonConvert.DeserializeObject<Dictionary<string,Dictionary<string,string>>(text)
I can then query for json["result"] and whatnot. With other API calls I get complex structures that I'm not sure how to handle. It's basically a bunch of key:value pairs, but some of the values are key:value pairs as well, which can't be put into a dictionary like I'm currently doing. I'm fairly new to C# so I'm not sure what to do here, is there some other data type like a Dictionary which doesn't have static types?
Here's the response:
{"response":
{
"action":"upload\/upload.php",
"doupload":
{
"result":"0",
"key":"89lh7760x4l"
},
"server":"live",
"result":"Success",
"current_api_version":"2.14"
}
}
My question would be: What is a good way to get this kind of data into a list that I can query for values?
What about creating a new class(s) to deal with the json? You can generate classes by using json2csharp using the example json.
public class Doupload
{
public string result { get; set; }
public string key { get; set; }
}
public class Response
{
public string action { get; set; }
public Doupload doupload { get; set; }
public string server { get; set; }
public string result { get; set; }
public string current_api_version { get; set; }
}
public class RootObject
{
public Response response { get; set; }
}
Then you can deserialise the json using:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var something = serializer.Deserialize<RootObject>(jsonString);
I ended up finding out about the dynamic type - Deserializing the text into a Dictionary<string,dynamic> allows it to have multiple types where some can be dictionaries as well. I can query it as I would expect but I just need to be sure what values are returned with each API call, and I need to cast it to a string.
string upload_key = (string)json["response"]["doupload"]["key"] //89lh7760x4l
I am trying to deal with a task of deserializing an object into a class of my design. The string I will receive looks like this:
{nodename:"node1", version:"v1", PARM1:"p1", PARM2:"p2" ,…, PARAMN:"pn"}.
As far as I understand, I will need a class for this json string, say Node is my class name. I know I can easily deal with nodename and version by adding two fields into my class Node. But what about the set of Params. Because the number of params in this string is dynamic and out of my control, I have no idea how to design my class. Please shed your light on this. Or do you think that is just impossible? Thanks in advance
your can use generic collections like List
public class ResultObject
{
public string NodeName { get; set; }
public string Version { get; set; }
public List<string> Params { get; set; }
}
Use the above code if Params name and type is not a concern. If you want Param1, Param2,... ParamN as your parameters, then:
public class ResultObject
{
public string NodeName { get; set; }
public string Version { get; set; }
public Dictionary<string, string> Params { get; set; }
}
then you can access Params with key like var x = Params["Param1"] and so on.
The easiest to represent your json in code is to deserialize to a Dictionary<string, object> or Dictionary<string, string> if you know all property values are strings.
Depending on your json serializer, the syntax may differ. This is using the Microsoft JavaScriptSerializer.
var serializer = new JavaScriptSerializer();
var dict = serializer.Deserialize<Dictionary<string, string>>(jsonString);
Console.WriteLine(dict["nodename"]); // "node1"
Console.WriteLIne(dict["PARM1"]); // "p1"
You can also use the Dictionary.Keys property to get additional information all the properties in the json string.
I've been trying to deserialize a specific JSON string using the JavaScriptSerializer class for a day now without success.
I've read a fair few posts on here, but cant find one that addresses a JSON string similar in design to the one I need to use, so I'm asking my own.
The string I need to deserialize is as follows:
["SomeName",[["alpha","bravo"],[1,6]],[["John","Bob","Paul","Ringo"],[1,2,1,8]]]
I thought this class would solve it, but I was evidently wrong:
[Serializable]
internal class OuterDeserializedObj
{
[Serializable]
internal class InnerDeserializedObj
{
public string Name { get; set; }
public List<List<string>> Array1 { get; set; }
public List<List<string>> Array2 { get; set; }
}
public List<InnerDeserializedObj> innerObj { get; set; }
}
Your Json is just an array (array of array of array of objects), Therefore the only way i can think of is to create a similar structure in c#.
(Using Json.Net)
string json = #"[""SomeName"",[[""alpha"",""bravo""],[1,6]],[[""John"",""Bob"",""Paul"",""Ringo""],[1,2,1,8]]]";
var arr = JArray.Parse(json);
string name = (string)arr.OfType<JValue>().First();
var arrays = arr.OfType<JArray>()
.Select(x => x.Select(y=>y.Select(z=>(string)z)
.ToList())
.ToList())
.ToList();