This question already has answers here:
How to handle both a single item and an array for the same property using JSON.net
(9 answers)
Closed 6 years ago.
Im with problem deserialize Json with newtonsoft json.
I have a class
[Serializable]
public class ValueAdd
{
[JsonProperty(PropertyName = "#id")]
public string Description { get; set; }
[JsonProperty(PropertyName = "#description")]
public string Id { get; set; }
}
[Serializable]
public class ValueAdds
{
public List<ValueAdd> ValueAdd { get; set; }
[JsonProperty(PropertyName = "#size")]
public string Size { get; set; }
}
And the API returning the stupid two things of format: One i can serialize correct:
"ValueAdds":
{
"#size": "3",
"ValueAdd":
[
{
"#id": "2103",
"description": "some property"
},
{
"#id": "2192",
"description": "some property"
},
{
"#id": "2196",
"description": "some property"
}
]
}
But when they return one property it didnt return a list.. only return on this way:
"ValueAdds":
{
"#size": "1",
"ValueAdd":
{
"#id": "2103",
"description": "some property"
}
}
Causing me a parser error with
JsonConvert.DeserializeObject<ValueAdds>(_response);
A first chance 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[myproperty]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
My question is, is there anyway to fix it?? I cant change the api response, need change from my side trying to parse if there is a list or not..
Actually, property should be either array or object. Your response should be consistent.
Anyway, to solve the problem, you should bind it to dynamic or object.
[Serializable]
public class ValueAdds
{
public dynamic ValueAdd { get; set; }
[JsonProperty(PropertyName = "#size")]
public string Size { get; set; }
}
Then you should check the ValueAdd type.
Because in your ValueAds ValueAdd is list but in your second json its a single entity so you can not assign it, you need to create another model
[Serializable]
public class ValueAdds2
{
public ValueAdd ValueAdd { get; set; }
[JsonProperty(PropertyName = "#size")]
public string Size { get; set; }
}
then
JsonConvert.DeserializeObject<ValueAdds2>(_response);
Related
This question already has answers here:
RestSharp - deserialize json response with invalid key name (contains a period )
(2 answers)
Closed 1 year ago.
{
"odata.metadata": "sometext",
"odata.nextLink": "sometext",
"value": [{
"odata.type": "SP.Data.RegionsListItem",
"odata.id": "07404daa-61b5-4947-af9f-38f29822f775",
"odata.etag": "\"3\"",
"odata.editLink": "Web/Lists(guid'65dc896b-df87-4145-98d9-57c7ea619e66')/Items(3)",
"FileSystemObjectType": 0,
"Id": 3,
"ServerRedirectedEmbedUri": null,
}]
}
this is an example of my Json string i cant change its key names any sugestion? thanks in advance.
Depending on the library you are using for deserialization you can mark model fields with corresponding attributes - for example JsonPropertyNameAttribute for System.Text.Json or JsonPropertyAttribute for Newtonsoft.Json.
Newtonsoft.Json:
public class Root
{
[JsonProperty("odata.metadata")]
public string OdataMetadata { get; set; }
[JsonProperty("odata.nextLink")]
public string OdataNextLink { get; set; }
[JsonProperty("value")]
public List<Value> Value { get; set; } // do the same for Value type
}
var result = JsonConvert.DeserializeObject<Root>(json);
System.Text.Json:
public class Root
{
[JsonPropertyName("odata.metadata")]
public string OdataMetadata { get; set; }
[JsonPropertyName("odata.nextLink")]
public string OdataNextLink { get; set; }
[JsonPropertyName("value")]
public List<Value> Value { get; set; }
}
var result = JsonSerializer.Deserialize<Root>(json);
When you create a class for your data, you can use annotations for the class members. For instance when using Newtonsoft.Json it works this way:
class MyData {
[JsonProperty("odata.metadata")]
public string Metadata {get;set;}
[JsonProperty("odata.nextlink")]
public string NextLink {get;set;}
...
}
With other libraries, the annotations may be named differently. Also make sure, you are importing the correct namespace and use the correct annotations for the library you are using. Ie for instance the System.Text.Json.JsonPropertyName annotation won't have any effect, when deserializing with Newtonsoft.Json and vice versa.
Then you can deserialize
var data = JsonConvert.DeserializeObject<MyData>(thejsonstring);
and access the property with its .NET name
var metadata = data.Metadata;
This question already has answers here:
Deserialize JSON with C#
(10 answers)
Closed 1 year ago.
{
"status": "success",
"data": {
"custid1": 723,
"custid2": 670,
"custid3": 430
}
}
It doesn't have key-value pair it just contains the value of two columns. I have tried it by converting it into a data table but not getting the required result.
You can create a class like below. and then use NewtonSoft to deserialize it to the class object.
public class Data
{
public int custid1 { get; set; }
public int custid2 { get; set; }
public int custid3 { get; set; }
}
public class Example
{
public string status { get; set; }
public Data data { get; set; }
}
Code to deserialize:
string json = <yourjson>;
Example ex = JsonConvert.DeserializeObject<Example>(json);
You can see the nugget package details here.
You can deserialize it to ExpandoObject
ExpandoObject object1 = JsonConvert.DeserializeObject<ExpandoObject>(json);
I am new to Json and trying to do some examples with it. I have Json data like this:
{
"Title": "The Avengers",
"Year": "2012",
"Rated": "PG-13",
"Released": "04 May 2012",
"Runtime": "143 min",
"Genre": "Action, Adventure, Sci-Fi",
"Director": "Joss Whedon",
"Writer": "Joss Whedon (screenplay), Zak Penn (story), Joss Whedon (story)",
"Actors": "Robert Downey Jr., Chris Evans, Mark Ruffalo, Chris Hemsworth",
"Plot": "Earth's mightiest heroes must come together and learn to fight as a team if they are going to stop the mischievous Loki and his alien army from enslaving humanity.",
"Language": "English, Russian, Hindi",
"Country": "USA",
"Awards": "Nominated for 1 Oscar. Another 38 wins & 79 nominations.",
"Poster": "https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU#._V1_SX300.jpg",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "8.0/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "92%"
},
{
"Source": "Metacritic",
"Value": "69/100"
}
],
"Metascore": "69",
"imdbRating": "8.0",
"imdbVotes": "1,200,683",
"imdbID": "tt0848228",
"Type": "movie",
"DVD": "25 Sep 2012",
"BoxOffice": "$623,279,547",
"Production": "Walt Disney Pictures",
"Website": "http://marvel.com/avengers_movie",
"Response": "True"
}
I can get the data and read it just fine but when it comes deserialize I get the following error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Deneme.Modeller.Main]' 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.
This is my code
string url = "http://www.omdbapi.com/?apikey=7663ce8e&t=Avengers";
WebRequest request = WebRequest.Create(url);
WebResponse reply;
reply = request.GetResponse();
StreamReader returninfo = new StreamReader(reply.GetResponseStream());
string getinfo = returninfo.ReadToEnd();
List<Main> Info = JsonConvert.DeserializeObject<List<Main>>(getinfo);
and for models this is first main:
public string Title { get; set; }
public string Year { get; set; }
public string Rated { get; set; }
public string Released { get; set; }
public string Runtime { get; set; }
public string Genre { get; set; }
public string Director { get; set; }
public string Writer { get; set; }
public string Actors { get; set; }
public string Plot { get; set; }
public string Language { get; set; }
public string Country { get; set; }
public string Awards { get; set; }
public string Poster { get; set; }
public List<Rating> Ratings { get; set; }
public string Metascore { get; set; }
public string imdbRating { get; set; }
public string imdbVotes { get; set; }
public string imdbID { get; set; }
public string Type { get; set; }
public string DVD { get; set; }
public string BoxOffice { get; set; }
public string Production { get; set; }
public string Website { get; set; }
public string Response { get; set; }
second one is for Ratings:
public string Source { get; set; }
public string Value { get; set; }
public virtual ICollection<Main> Mains { get; set; }
It's about Json array, but I looked asked questions about this problem and tried to fix it but no luck. What am I missing?
You are trying to deserialize a single object of type Main into a list of objects.
You can either change your code to deserialize into a single object instead of a list or you can alter your JSON to represent an array of objects.
The first option would be
Main Info = JsonConvert.DeserializeObject<Main>(getinfo);
And the second option
[{"Title":"The Avengers","Year":"2012","Rated":"PG-13","Released":"04 May 2012","Runtime":"143 min","Genre":"Action, Adventure, Sci-Fi","Director":"Joss Whedon","Writer":"Joss Whedon (screenplay), Zak Penn (story), Joss Whedon (story)","Actors":"Robert Downey Jr., Chris Evans, Mark Ruffalo, Chris Hemsworth","Plot":"Earth's mightiest heroes must come together and learn to fight as a team if they are going to stop the mischievous Loki and his alien army from enslaving humanity.","Language":"English, Russian, Hindi","Country":"USA","Awards":"Nominated for 1 Oscar. Another 38 wins & 79 nominations.","Poster":"https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU#._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"8.0/10"},{"Source":"Rotten Tomatoes","Value":"92%"},{"Source":"Metacritic","Value":"69/100"}],"Metascore":"69","imdbRating":"8.0","imdbVotes":"1,200,683","imdbID":"tt0848228","Type":"movie","DVD":"25 Sep 2012","BoxOffice":"$623,279,547","Production":"Walt Disney Pictures","Website":"http://marvel.com/avengers_movie","Response":"True"}]
(simply add brackets)
Which option you have to choose is depending on your requirements, i.e. if you want to allow multiple objects or just one.
Main Info = JsonConvert.DeserializeObject<Main>(getinfo);
Your json string has only one Main object, you were trying to get a List
You try to deserialize one JSON object into a list of objects.
This is an example of simple object:
{ "field": 123 }
To deserialize it you need to:
var obj = JsonConvert.DeserializeObject<SomeModel>(json);
But if you have an array of objects:
[{ "field": 123 }, { "field": 123 }]
You will be able to deserialize them to a list like this:
var objs = JsonConvert.DeserializeObject<SomeModel[]>(json);
or
var objs = JsonConvert.DeserializeObject<List<SomeModel>>(json);
Solutions to your question:
Change deserialization type to a single object.
Wrap your JSON around with []
when we call api 'http://www.omdbapi.com/?apikey=7663ce8e&t=Avenger' we gets an objet not an array of object
try
var info = JsonConvert.DeserializeObject<Main>(getinfo);
If you want list of movies try a other api b.e.: themoviedbAPI
I have a JSON file that has been serialized through an API, in which I need to deserialize it to use the data it generated in my code. The issue is that I'm getting an Exception Unhandled error in which I have tried to understand the solution to the error, but I have had a few days off tunnel vision with this issue.
I have tried my best to link my issue with other threads, but have been lost for a few days. I did get some form of sprint finish with setting up a {get { return } } with a property but due to the setup of the code when serializing I couldn't do that. Instead I've tried to put the file outputted in a simple location and tried desalinizing it based on the file location.
ImageModeration image1 = JsonConvert.DeserializeObject<ImageModeration>(File.ReadAllText(#"C:\ModerationOutput.json"));
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(#"C:\ModerationOutput.json"))
{
JsonSerializer serializer = new JsonSerializer();
ImageModeration image2 = (ImageModeration)serializer.Deserialize(file, typeof(ImageModeration));
}
Here is my json file
[
{
"ImageUrl": "URL",
"ImageModeration": {
"CacheID": "396a972f-79ae-4b31-a54c-0ba3314318fa_637026883058218816",
"Result": false,
"TrackingId": "UKS_ibiza_464a60be-f57d-4ee1-aa37-13d04f151fdd_ContentModerator.F0_4ae15371-36c9-4cb2-8e21-83381a29432c",
"AdultClassificationScore": 0.0048455675132572651,
"IsImageAdultClassified": false,
"RacyClassificationScore": 0.011258091777563095,
"IsImageRacyClassified": false,
"AdvancedInfo": [
{
"Key": "ImageDownloadTimeInMs",
"Value": "37"
},
{
"Key": "ImageSizeInBytes",
"Value": "34854"
}
],
"Status": {
"Code": 3000,
"Description": "OK",
"Exception": null
}
},
"TextDetection": null,
"FaceDetection": null
}
]
This error comes from the first line of code.
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array (e.g. [1,2,3]) into type
'convertingJSON.Program+ImageModeration' 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.'
Specific to your JSON string that you have posted, you can refer to the following code snippet to deserialize your string into its respective components.I am using the Newtonsoft JSON library which is a popular high-performance JSON framework for .NET. A working example can be found at: https://dotnetfiddle.net/RmXNHM
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string json=#"[{'ImageUrl':'URL','ImageModeration':{'CacheID':'396a972f-79ae-4b31-a54c-0ba3314318fa_637026883058218816','Result':false,'TrackingId':'UKS_ibiza_464a60be-f57d-4ee1-aa37-13d04f151fdd_ContentModerator.F0_4ae15371-36c9-4cb2-8e21-83381a29432c','AdultClassificationScore':0.004845567513257265,'IsImageAdultClassified':false,'RacyClassificationScore':0.011258091777563095,'IsImageRacyClassified':false,'AdvancedInfo':[{'Key':'ImageDownloadTimeInMs','Value':'37'},{'Key':'ImageSizeInBytes','Value':'34854'}],'Status':{'Code':3000,'Description':'OK','Exception':null}},'TextDetection':null,'FaceDetection':null}]";
var Sresponse = JsonConvert.DeserializeObject<List<RootObject>>(json);
foreach(var value1 in Sresponse)
{
Console.WriteLine(value1.ImageUrl);
Console.WriteLine(value1.ImageModeration.CacheID);
}
}
}
public class AdvancedInfo
{
public string Key { get; set; }
public string Value { get; set; }
}
public class Status
{
public int Code { get; set; }
public string Description { get; set; }
public object Exception { get; set; }
}
public class ImageModeration
{
public string CacheID { get; set; }
public bool Result { get; set; }
public string TrackingId { get; set; }
public double AdultClassificationScore { get; set; }
public bool IsImageAdultClassified { get; set; }
public double RacyClassificationScore { get; set; }
public bool IsImageRacyClassified { get; set; }
public List<AdvancedInfo> AdvancedInfo { get; set; }
public Status Status { get; set; }
}
public class RootObject
{
public string ImageUrl { get; set; }
public ImageModeration ImageModeration { get; set; }
public object TextDetection { get; set; }
public object FaceDetection { get; set; }
}
Output:
URL
396a972f-79ae-4b31-a54c-0ba3314318fa_637026883058218816
Use this site to convert you're JSON to a C# object and then deserialize to it.
According to the error it seems you may have been missing a property i.e. the object does not correspond to the JSON
I am new to Newtonsoft.Json so please excuse my ignorance - however I am coming up against this issue when trying to Deserialize the following Json to either a c# object or indeed manually.
The Json is
{
"travellerInfo": [
{
"passengerData": {
"travellerInformation": {
"passenger": [
{
"type": "ADT",
"firstName": "MARY MRS"
},
{
"type": "INF",
"firstName": "JOSHUA"
}
],
"traveller": {
"surname": "SMITH",
"quantity": "2"
}
}
}
},
{
"passengerData": {
"travellerInformation": {
"passenger": {
"type": "ADT",
"firstName": "JOHN MR"
},
"traveller": {
"surname": "SMITH",
"quantity": "1"
}
}
}
}
]
}
So as you can see, on the first 'passenger' item, this returns as an Array, however on the second 'passenger' item, it doesn't return as an array, just a single block. I am not in control of the Json being sent to me - it comes from an external system. My C# classes are
public class Passenger
{
public string type { get; set; }
public string firstName { get; set; }
}
public class Traveller
{
public string surname { get; set; }
public string quantity { get; set; }
}
public class TravellerInformation
{
public List<Passenger> passenger { get; set; }
public Traveller traveller { get; set; }
}
public class PassengerData
{
public TravellerInformation travellerInformation { get; set; }
}
public class TravellerInfo
{
public PassengerData passengerData { get; set; }
}
and I call
var example = JsonConvert.DeserializeObject<TravellerInfo>(jsonString);
I am getting the error
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Script1.TravellerInfo' 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.
Path 'travellerInfo', line 57, position 20.
I tried putting a [JsonArray] attribute on the Passenger class to force it to deserialise as an array/list, but same error occured as I think the underlying item is a JProperty instead of a JObject.
So how can I get this to work when the ["passenger"] can come back as both an Array and Single object ?
Cheers in Advance
You can try deserialize it as dynamic and then do some checks to types. Check if it is IEnumerable.
That should do the job.
Try this. Replace List<Passenger> with object passenger in TravellerInformation:
public class Traveller
{
public string surname { get; set; }
public string quantity { get; set; }
}
public class TravellerInformation
{
public object passenger { get; set; }
public Traveller traveller { get; set; }
}
public class PassengerData
{
public TravellerInformation travellerInformation { get; set; }
}
public class TravellerInfo
{
public PassengerData passengerData { get; set; }
}
And call this by passing List<TravellerInfo> instead of TravellerInfo:
var example = JsonConvert.DeserializeObject<List<TravellerInfo>>(jsonString);
Also for these cases you can use this service which automatically creates C# classes from JSON objects, so you don't have to worry about correctness.