Can't deserialize JSON to Object [duplicate] - c#

This question already has an answer here:
Cannot deserialize the current JSON array (e.g. [1,2,3])
(1 answer)
Closed 2 years ago.
I'm doing some testing in my program and I wanted to transform APIGatewayProxyResponse into a object to access it's values.
So an example of what my APIGatewayProxyResponse.Body (it's a string) looks like:
"[{"date": "2020-03-06", "value": 35},{"date": "2020-03-09", "value": 233}]"
I wanted to turn this into a dictionary at first, but I realized that perhaps it's not possible because a dictionary has unique key values and here I have a "date" and "value" properties that aren't unique.
var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(APIGatewayProxyResponse.Body);
Had a error, which proved my concern:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
So I made an ResponseObject to achieve the same result
public class ResponseObject
{
public string date { get; set; }
public double value { get; set; }
}
var dic = JsonConvert.DeserializeObject(APIGatewayProxyResponse.Body,typeof(ResponseObject));
But had the same error! I don't understand, the browser can look at the response and recognises it's a JSON format, so why ins't the same happening in in ASP.NET?

Because your Json is an array, So, you can Deserialize with IEnumerable type.
Try this:
var dic = JsonConvert.DeserializeObject<IEnumerable<ResponseObject>>(APIGatewayProxyResponse.Body);

Related

JsonConvert.DeserializeObject error while deserializing a string

I am trying to deserialize a json string that is coming from a js code, the data holds the json string that I want to deserialize.
The coming string is:
{"metalRingID":"FB11111","birdData":[{"longitude":-3.0851070084624497,"latitude":51.02832183751735,"gridRef":"ST2426","date":"2020-01-05T00:00:00"},{"longitude":-2.233409881591797,"latitude":51.5276985168457,"gridRef":null,"date":"2020-01-02T00:00:00"},{"longitude":-2.3790299892425537,"latitude":51.4547004699707,"gridRef":null,"date":"2020-01-03T00:00:00"},{"longitude":-1.6884700059890747,"latitude":51.68299865722656,"gridRef":null,"date":"2020-01-05T00:00:00"}]}
This is the model to hold that data:
using System;
using Newtonsoft.Json;
namespace BirdProject.Model.ViewModel
{
public class birdDataSolutionVM
{
[JsonProperty("metalRingID")]
public string metalRingID;
[JsonProperty("birdData")]
public List<birdRecordVM> birdData;
}
}
This is the line that should do the job.
var birdRecords = JsonConvert.DeserializeObject<List<birdDataSolutionVM>>(data);
The error I am receiving is the next:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[BirdProject.Model.ViewModel.birdDataSolutionVM]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.\nTo 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) 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.\nPath 'metalRingID', line 1,
position 15.
You should be deserializing into the type, not an array of the type. It's a single object containing an array, but the root json is not an array.
var birdRecords = JsonConvert.DeserializeObject<birdDataSolutionVM>(data);

Json array exception

I create a Json file and insert some objects of my class inside it, like this:
private async void Save_Clicked(object sender, EventArgs e)
{
Note NoteNew = new Note
{
FraseGiorno = obj1.FraseGiornaliera,
Nota = TestoNota.Text,
Data= DateTime.Today.ToString().Remove(10,9),
};
File.WriteAllText(NotesFile, JsonConvert.SerializeObject(NoteNew));
}
Then when I try to read the file and deserialize the json I get this exception. how could i solve?
string NotesFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Note.json");
ObservableCollection<Note> listNote = new ObservableCollection<Note>();
FraseClass obj1;
public NotePage(FraseClass obj1)
{
InitializeComponent();
this.obj1 = obj1;
if (File.Exists(NotesFile))
{
listNote = JsonConvert.DeserializeObject<ObservableCollection<Note>>(File.ReadAllText(NotesFile));
CollectionNote.ItemsSource = listNote;
}
}
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.ObjectModel.ObservableCollection`1[MotiVApp.NotePage+Note]' 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) 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 'FraseGiorno', line 1, position 15.'
I don't understand why the exception refers to the 'FraseGiorno' property
You are serializing an object into the file, but deserializing into a collection.
If you absolutely must use an ObservableCollection, separate the initialization and deserialization steps:
var note = JsonConvert.DeserializeObject<Note>(File.ReadAllText(NotesFile));
listNode.Add(note);
CollectionNote.ItemsSource = listNote;

Getting A List From Service Async

While trying to get list from an url, program stops and throw an exception like that
An exception of type 'System.AggregateException' occurred in mscorlib.dll but was not handled in user code
also
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[WebAPIDemo.Models.Person]' 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) 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 'Message', line 1, position 11.
I thought its because of using IEnumerable<MyObject> in my program but when I use only MyObject it goes away from this point but it crush into somewhere else.
I'm stuck now.
Here is my code:
CONTROLLER.CS:
private IEnumerable<Person> CallPersonListServiceAsync(HttpClient ins, string url)
{
var content = ins.GetAsync(url).Result.Content;
var personsList = content.ReadAsAsync(typeof(IEnumerable<Person>)).Result as IEnumerable<Person>;
return personsList;
}
PERSON.CS:
public class Person
{
public string name { get; set; }
public string surname { get; set; }
public DateTime dob { get; set; }
}
Is it really happening that because I'm using IEnumerable or something different. Thanks
The error is telling you that the JSON you're receiving is an object, not a collection. So you have to deserialize it to an object, not a collection. Unless the JSON is very different from what you expect (that is, not a Person at all) then you would simply deserialize it to a Person:
var result = content.ReadAsAsync(typeof(Person)).Result as Person;
Which would of course necessitate changing the return type (and name) of your method:
private Person CallPersonServiceAsync(HttpClient ins, string url)
Alternatively, instead of changing the method signature you could manufacture a list from that single person and return that:
return new List<Person> { result };
Additionally, the async nature of your code is very broken. For one thing, you are calling .Result explicitly which is almost always the wrong approach. Second, your method's name advertises it as an async method but it's not async at all.
You can correct both of these problems by making use of async and await:
private async Task<Person> CallPersonServiceAsync(HttpClient ins, string url)
{
var content = (await ins.GetAsync(url)).Content;
var result = (await content.ReadAsAsync(typeof(Person))) as IEnumerable<Person>;
return result;
}

How to handle input of varying datatype during deserialization?

I'm trying to download json data where one of the attributes is "easting". For the majority of the json dataset, "easting" is an integer, but there are a handful of cases in which "easting" is a list of integers as shown below:
"easting" : 357570 ,
...
"easting" : [ 434939, 434942 ] ,
My original code had anticipated "easting" to be an int when its class was declared as follows:
public class Item
{
public int easting { get; set; }
}
However, I keep getting errors saying that I cannot convert a type int to a type int []. If I adjust the class definition to allow easting to be of type int [], I simply get the reverse error - I cannot convert a type int [] to a type int.
How can I go about handling this? Is there any way to account for a varying input datatype during the deserialization process?
In the end, I followed the suggestion from #stuartd and swtiched from JavaScriptSerializer to Json.net for the deserialization process, which allowed me to follow along with the question posted here and resolve my issue.

Json Deserialization with same property name with different case

I want to understand how Json.NET deserializes a JSON object to corresponding c# object when we have multiple property names with different cases(I know this is not a good practice, but just curious to know how JSON.NET deals with this).
I have a c# object defined as below:
public class TestModel
{
public string Name { get; set; }
public bool IsEmployee { get; set; }
}
And json object as
{ "Name": "TestName","Isemployee":true, "isemployee":false};
Then, if I use the JSON.NET de-serialize method to convert above json string to TestModel object, which one of those two properties will be assigned to IsEmployee variable? And why?
Thanks.
In deserialization, Json.NET attempts case insensitive matching of an attribute if exact matching fails, as discussed here. This is in contrast to the built-in .NET JSON serializers, see here.
If multiple matches are detected, the last match takes precedence.

Categories

Resources