Json is not deserializing correctly into a class - c#

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[]

Related

Using Newtonsoft JsonConvert to serialize and deserialize simple class

I'm trying to simply serialize and deserialize a simple class with JsonConvert.SerializeObject(obj) and JsonConvert.DeserializeObject(string).
I'm using this in a custom TypeConverter for a QueryParameter in .NET Web API Core 2.1.
But I'm getting very strange behavior. My class looks like this:
public class ListRequestDto {
public bool? WithCreator { get; set; }
public int? Skip { get; set; }
public int? Limit { get; set; }
}
And I'm trying to do the following:
var test = new ListRequestDto {
WithCreator = true,
Skip = 0,
Limit = 15
};
string ttt = JsonConvert.SerializeObject(test);
But I'm getting the following output:
"MyNameSpace.ListRequestDto"
If I try it the other way around:
string json = "{ WithCreator: true, Skip: 0, Limit: 15 }";
JsonConvert.DeserializeObject<ListRequestDto>(json);
I get the following exception:
Newtonsoft.Json.JsonSerializationException: "Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'MyNameSpace.ListRequestDto' because the type requires a JSON string value to deserialize correctly.
To fix this error either change the JSON to a JSON string value 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 'Skip', line 1, position 8."
I tried to remove the nullable fields (replacing them with regular primitives) but that resulted int he exact same error.
The strange thing is, that if I provide the same class as a body it works. And as far as I know Web API Core also uses the Newtonsoft Json Parser.
I do not know why it is necessary, but when I put [JsonObject] on my class it suddenly works.
The exception actually told me to do that, but I do not understand why it is necessary when in no documentation this is used in such a case.
So bascially doing the following solved the problem:
[JsonObject]
public class ListRequestDto {
public bool? WithCreator { get; set; }
public int? Skip { get; set; }
public int? Limit { get; set; }
}

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);
}

Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Newtonsoft.Json.Linq.JArray'

I am testing my Web API. Mocking the data I have this:
var objs = ((JArray)JsonConvert.DeserializeObject("{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}")).Values<JObject>();
Which gives me the error:
Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Newtonsoft.Json.Linq.JArray'
The thing is it was working. I must have changed something, but I don't know what.
My intent is to convert this JSON object to a list of .NET objects called Print which has the fields:
PrintId
Header
TX
CompnayRef
Just make a class and deserialize it.
public class Print
{
public int PrintId { get; set; }
public string Header { get; set; }
public string TC { get; set; }
public string CompanyRef { get; set; }
}
Print printObj = JsonConvert.DeserializeObject<Print>(yourJson);
printObj.PrintId = //...
As the message says, your object is JObject so don't cast it to JArray. Try this:
var objs = JsonConvert.DeserializeObject("{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}");
Update To get a collection List<Print>, your JSON needs to be an array. Try this (I made your JSON an array and added a second object):
string json = "[{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}"
+ ",{ \"PrintId\":20,\"Header\":\"header2\",\"TC\":\"tc2\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}]";
var objs = JsonConvert.DeserializeObject<List<Print>>(json);
//The loop is only for testing. Replace it with your code.
foreach(Print p in objs){
Console.WriteLine("PrintId: " + p.PrintId);
Console.WriteLine("Header: " + p.Header);
Console.WriteLine("TC: " + p.TC);
Console.WriteLine("CompanyRef: " + p.CompanyRef);
Console.WriteLine("==============================");
}
public class Print
{
public int PrintId { get; set; }
public string Header { get; set; }
public string TC { get; set; }
public string CompanyRef { get; set; }
}
Here is a fiddle.
Simply because { } is a jobject notation, to make it a jarray just put square brackets around it e.g. [{ }]. So in your case, just putting these two chars fixes the problem.
var objs = ((JArray)JsonConvert.DeserializeObject("[{ \"PrintId\":10,\"Header\":\"header\",\"TC\":\"tc\",\"CompanyRef\":\"00000000-0000-0000-0000-000000000000\"}]")).Values<JObject>();
you can try here
https://dotnetfiddle.net/RmgGw8
Note: You said it was working before. So this string input probably is a result of a serialization. You did not have a problem before, because your input was always an array with multiple items until this one. And your serializer is probably producing a single object (output starting with '{') instead of an array (output starting with '[') for single item arrays.
serializing List with single object as JSON object not JSON array
For me I was putting empty string as an object which caused the issue, I switched to "{}" which fixed my issue

How to convert a Json string to a class that has a list in Json.Net with C# when the json has an array one level deeper

I have a C# Application in which I am using Json.Net from Nuget.
I get a json from my server which I need to convert into a C# object and with a few modifications I will send it back to the server as json.
Here's my model in C# (which I got after converting the server xsd)
public class Tags
{
public List<Tag> tagData { get; set; }
}
public class Tag
{
public string name {get; set;}
}
Here's my JSON string that is obtained from the server and an attempt at conversion to my model
//Json string obtained from server (hardcoded here for simplicity)
string json = "{tagData: {tags : [ { name : \"John\"}, { name : \"Sherlock\"}]}}";
//An attempt at conversion
var output = JsonConvert.DeserializeObject<Tags>(json);
This is the exception I get with the above code
An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[jsonnetExample.Tag]' 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<T>) 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 'tagData.tags', line 1, position 17.
After understanding the above message I tried the following 2 things in the hope of fixing it.
A.I tried putting a JsonProperty to my first model.
[JsonProperty(PropertyName = "tags")]
This didn't throw the exception anymore but the output tagData was null.
B. I modified my model as follows
public class Tags
{
public WrapTag tagData { get; set; }
}
public class WrapTag
{
public List<Tag> tags { get; set; }
}
public class Tag
{
public string name {get; set;}
}
This didn't throw any exception and populated the objects as expected. But Now I lost the one to one mapping between xsd(classes from the server) to my client model classes. Is it possible to get this deserialization working without the creation of the WrapTag class?
I would be very glad if someone can point me in the right direction.
Thanks in advance.
Here's one option, using JObject.Parse:
string json = "{tagData: {tags : [ { name : \"John\"}, { name : \"Sherlock\"}]}}";
List<Tag> tagList = JObject.Parse(json)["tagData"]["tags"].ToObject<List<Tag>>();
// or:
// List<Tag> tagList = JObject.Parse(json).SelectToken("tagData.tags")
// .ToObject<List<Tag>>();
Tags tags = new Tags { tagData = tagList };

Categories