json save object to list - c#

Can anyone tell me how to fix this?
class Movie
{
public string Name { get; set; }
public int Year { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Movie> _data = new List<Movie>();
_data.Add(JsonConvert.DeserializeObject<Movie>(File.ReadAllText(#"mov.txt")));
Console.ReadKey();
}}
[{"Name" : "John","Year" : "1990"},
{"Name" : "Mark","Year" : "2005"}]
Theres Exception:
Additional information: Cannot deserialize the current JSON array
(e.g. [1,2,3]) into type 'testjson.Movie' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly.
Thank you.

It's a JSON array, so you need to deserialize as such:
JsonConvert.DeserializeObject<Movie[]>
So you can call AddRange(), which accepts an IEnumerable<Movie>:
_data.AddRange(JsonConvert.DeserializeObject<Movie[]>(File.ReadAllText(#"mov.txt")));
But in this case you can deserialize the list itself:
List<Movie> _data;
_data = JsonConvert.DeserializeObject<List<Movie>>(File.ReadAllText(#"mov.txt")));

try this (thanks to CodeCaster):
_data.AddRange(JsonConvert.DeserializeObject<List<Movie>>(File.ReadAllText(#"mov.txt")));
because this
[
{ ... },
{ ... },
...
]
in your json means that it is an array. So you have to deserialize it as an array.

Related

Json is not deserializing correctly into a class

I'm trying to convert an array into a class. So I get the array, then serialize it with JsonConvert as you can see below:
var gameResponse = GetGame(Id);
var returnedArray = gameResponse.Result.Results;
var json = JsonConvert.SerializeObject(returnedArray);
var result = JsonConvert.DeserializeObject<T>(json);
I can see the results of this in Visual Studio debug mode and "json" looks like this:
[
{
\"CreatorId\":\"41c5321e-6f37-4d4f-92f7-fc381be0fc62\",
\"GameId\": \"3938\",
\"Type\": \"2\",
\"CreateDate\": \"1/2/2017\",
\"TeamId\": \"2394\",
\"LeaderId\": \"34922\",
\"CountryCode\": \"23\",
\"SalesRank\": \"4\",
\"Title\": \"Space Shooter Max\",
\"TeamName\": \"The One\",
\"TeamMembers\" : \"4\"
}
]
However, when the code hits the next line:
var result = JsonConvert.DeserializeObject<T>(json); // In this case, <T> is <Game>
I get this error:
JsonSerializationException: Cannot deserialize the current JSON array
(e.g. [1,2,3]) into type 'GameLabs.Game' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly.
GameLabs.Game is a class that looks like this:
public sealed class Game
{
public string CreatorId { get; set; }
public string GameId { get; set; }
public string Title { get; set; }
public DateTime CreateDate { get; set; }
public string CountryCode { get; set; }
}
I'm not sure why it won't accept the JSON.
Does anyone see anything wrong?
Thanks!
If you examine your JSON, it is not an a single object, but instead a collection. "[..]" signifies a collection.
For example,
[ "Ford", "BMW", "Fiat" ]
The above Json implies a array of string with 3 elements. This is similar to your Json as well.
Hence you need to deserialize your Json to a Collection as well.
var result = JsonConvert.DeserializeObject<List<T>>(str);
You can read more on Json Arrays here
As I can see, your JSON is array and you should write somethink like this:
var result = JsonConvert.DeserializeObject<T[]>(json);
T=>T[]

Deserialize a byte array containing a dictionary with JSON.Net [duplicate]

This question already has answers here:
Newtonsoft Json Deserialize Dictionary as Key/Value list from DataContractJsonSerializer
(3 answers)
Serialize dictionary as array (of key value pairs)
(6 answers)
Serialize Dictionary<,> as array in Json.NET [duplicate]
(2 answers)
Closed 4 years ago.
I am facing the following scenario. A project of mine is throwing an event that contains the following object:
public class MyEvent : BaseEvent
{
public long Id { get; set; }
public Dictionary<string, long> Pairs { get; set; }
}
I received the event and read the data as byte[] on my receiver side. The current code I have to read any generic event is:
public static T Decode(byte[] data)
{
var serializer = JsonSerializer.Create(new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
using (var stream = new MemoryStream(data))
{
using (var sr = new StreamReader(stream, Encoding.UTF8))
{
var jr = new JsonTextReader(sr);
var aux = Encoding.UTF8.GetString(data);
return serializer.Deserialize(jr, typeof(T)) as T;
}
}
}
where T is my class MyEvent . Unfortunately the thrown exception is:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.Int64]' 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 'OperationTimePairs', line 1, position 61.
The way I read it is that the object received doesn't have the correct format.. however if I try to read it through var aux = Encoding.UTF8.GetString(data); I can see that the structure is the correct one. Any idea how can I fix this? Thanks!
EDIT:
Json Example:
{
"Timestamp":"\/Date(1540996292134)\/",
"Pairs":[
{
"Key":"first time",
"Value":28
},
{
"Key":"second time",
"Value":30
},
{
"Key":"third time",
"Value":101
},
{
"Key":"operation time",
"Value":231
}
],
"Id":123637
}
I think that your classes don't match the json string structure.
Given the following json string:
{
"Timestamp":"\/Date(1540996292134)\/",
"Pairs":[
{
"Key":"first time",
"Value":28
},
{
"Key":"second time",
"Value":30
},
{
"Key":"third time",
"Value":101
},
{
"Key":"operation time",
"Value":231
}
],
"Id":123637
}
You can change your models to match the json structure, something like this:
public class MyEvent : BaseEvent
{
public long Id { get; set; }
public List<KeyValuePair<string, long>> Pairs { get; set; }
[JsonIgnore]
public Dictionary<string, long> PairsDictionary
{
get
{
if (Pairs == null)
{
return new Dictionary<string, long>();
}
return Pairs.ToDictionary(pair => pair.Key, pair => pair.Value);
}
}
}
public class BaseEvent
{
public DateTime Timestamp { get; set; }
}
Please note:
PairsDictionary is a non-serializable property based on Pairs
Given that you didn't provide the class definition of BaseEvent, I will assume that it has 1 property only
Testing the deserialization:
string json = #"{
""Timestamp"":""\/Date(1540996292134)\/"",
""Pairs"":[
{
""Key"":""first time"",
""Value"":28
},
{
""Key"":""second time"",
""Value"":30
},
{
""Key"":""third time"",
""Value"":101
},
{
""Key"":""operation time"",
""Value"":231
}
],
""Id"":123637
}";
MyEvent eventData = JsonConvert.DeserializeObject<MyEvent>(json);
Or as an alternative (using generics):
T data = JsonConvert.DeserializeObject(json, typeof(T)) as T;

Cannot deserialze the current JSON array into type

I'm trying to deserialize following JSON data :
{
"bids": [
[
"392031.00000000",
"0.00254444"
],
[
"390000.00000000",
"0.52917503"
],
......
],
"asks": [
[
"392999.00000000",
"1.00000000"
],
[
"393000.00000000",
"0.31572236"
],
.....
]
}
I've looked into similar question such as this one, but I'm not getting close result and also noticed that in that question the structure of JSON is not similar.
My code for deserialization is as below
public class OrderBookElement
{
// I've also tried below commented code
//[JsonProperty(PropertyName = "0")]
//public double price { get; set; }
//[JsonProperty(PropertyName = "1")]
//public double volume { get; set; }
List<double> values;
}
public class OrderBookResponse
{
[JsonProperty(PropertyName = "bids")]
List<OrderBookElement> bids { get; set; }
[JsonProperty(PropertyName = "asks")]
List<OrderBookElement> asks { get; set; }
}
Below is code that I use for deserialization
var ordBook = JsonConvert.DeserializeObject<OrderBookResponse>(jsonResponse);
This gives me error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'RestAPI.OrderBookElement' 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.
The JSON you've shown would be represented by:
public class OrderBookResponse
{
[JsonProperty("bids")]
public List<List<string>> Bids { get; set; }
[JsonProperty("asks")]
public List<List<string>> Asks { get; set; }
}
The bids and asks properties in the JSON are each just an array of arrays of strings.
I'd suggest deserializing to a model which matches the JSON, then convert that into a more useful model separately. It may be possible to apply attributes to your class to persuade Json.NET to do what you want, but I tend to think that by the time there's a significant discrepancy (not just the property names), it's worth separating the two models out, one for serialization and one for use within the rest of your code.

Able to deserialize string type but not object type

I am using C# with JSON.NET. Below are the two types.
JSON object - var user = { "name": "test", "title": "mytitle"};
JSON String - var user1 = "{ \"name\": \"test\", \"title\": \"mytitle\" }";
Using Newtonsoft.Json to deserialize the JSON object. C# Code in which I am handling JSON.
public class sampledata
{
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("title")]
public string title { get; set; }
}
public void SampleEvent(string param)
{
sampledata s = JsonConvert.DeserializeObject<sampledata>(param);
}
When I got JSON String in param the deserialization is fine. But when I got JSON object in param - First error I am getting is
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'UCRS.MainWindow+sampledata' 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.
So I changed the code as :
List<sampledata> s = JsonConvert.DeserializeObject<List<sampledata>>(param);
Then I am facing different issue
" Unexpected character encountered while parsing value: o. Path '',
line 1, position 1."
When some event is raised in web page I am handling that event in c# using webbrowser objectforscripting. I always get the JSON object as param. How to deserialize JSON object in C#? Please help
Its pretty simple..working for both
string jsonObject = #"{""name"":""test"",""title"":""mytitle""}";
var jsonString = "{ \"name\": \"test\", \"title\": \"mytitle\" }";
var values1 = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonObject);
var values2 = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
This is also working
var values3 = JsonConvert.DeserializeObject<sampledata>(jsonObject);
I created JObject
JObject jObject = new JObject
{
{"name", "test" },
{"title", "mytitle" }
};
string jObjectStr = jObject.ToString();
var values = JsonConvert.DeserializeObject<sampledata>(jObjectStr);
The updated line of code:
List<sampledata> s = JsonConvert.DeserializeObject<List<sampledata>>(param);
is perfectly fine.
The problem here is that the deserializer is expecting an array when you are trying to deserialize to a list.
Try making it an array. Add this line of code to the param string:
param ="["+param+"]";//make it an array before deserialization
Complete code:
public class sampledata
{
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("title")]
public string title { get; set; }
}
public void SampleEvent(string param)
{
param ="["+param+"]";//make it an array before deserialization
List<sampledata> s = JsonConvert.DeserializeObject<List<sampledata>>(param);
}

Deserialize array in JSON into class/object

I'm trying to store JSON data into a class. I could deserialize my otherJSON string into class by: var ser = JsonConvert.DeserializeObject<ClsResult>(myJSON); before I got stuck with array.
{
\"Test\": [{
\"FirstBool\":1,
\"aString\":\"hello\"
}]
}
This is my class for JSON:
public class Test
{
[JsonProperty("FirstBool")]
public bool FirstBool { get; set; }
[JsonProperty("aString")]
public string aString { get; set; }
}
public class ResultObject
{
[JsonProperty("Test")]
public List<Test> Test { get; set; }
}
How I deserialize my non-array JSON:
var ser = JsonConvert.DeserializeObject<ResultObject>(myJSON);
What changes do I need to make it work again?
Edited answer
Your json string as I've noticed later contains object named Test which is basically an array of objects ( object[] ).
As you can see from the json string :
{
"Test": [{
"FirstBool" : 1,
"aString" : "hello"
}]
}
[ means that json object begins an array type and ] means that json object ended an array type.
{ means that json object begins an object type and } means that json object ended an object type.
Which in your case will require to make kind of a custom deserializer using existing methods from Newtonsoft.Json library.
Example for the Test object could be :
JObject obj = JObject.Parse(jsonString);
// now your obj contains field named "Test" that is of type object[]
// to retrieve informations you have to select "Test" token
JToken testToken = obj.SelectToken("Test");
// your token contains now something like " [{ "FirstBool" : 1, "aString" : "hello" }]"
// which basically is an array
// meaning that you have to iterate through this
foreach(var child in token.Children())
{
// and convert it to a Test object
Test test = JsonConvert.DeserializeObject<Test>(child.ToString());
// test now is fully deserialized object
}
Deserialize it as a list:
JsonConvert.DeserializeObject<List<Test>>(json);
...instead of a wrapper object.

Categories