So I have a problem with DeserializeObject with an json array and I cant find what I am doing wrong here:
{"name":"Pannbiff n\u00f6tf\u00e4rs stekt","number":1128,"nutrientValues":
{"energyKj":694,"energyKcal":166,"protein":17.2,"fat":7.6,"carbohydrates":7}}
My model looks like this:
And my code looks like:
var responseText = streamReader.ReadToEnd();
var jsonSerializer = JsonConvert.DeserializeObject(responseText);
public class Asware
{
public IEnumerable<NutrientValues> nutrientValues { get; set; }
}
public class NutrientValues
{
public int energyKcal { get; set; }
public double protein { get; set; }
public double carbohydrates { get; set; }
public int fat { get; set; }
}
Can't see what can be wrong here I have also tried:
JsonConvert.DeserializeObject>(responseText)
The problem here is that in your source JSON, nutrientValues is a single object, not an array of objects.
If you change your model as follows it should serialise correctly:
public class Asware
{
public NutrientValues nutrientValues { get; set; }
}
Alternatively, if you have control of the JSON, then you can modify it to contain an array of nutrients as follows, the [ ] characters indicate multiple items.
{"name":"Pannbiff n\u00f6tf\u00e4rs stekt","number":1128,"nutrientValues":
[{"energyKj":694,"energyKcal":166,"protein":17.2,"fat":7.6,"carbohydrates":7}]}
Related
Source Code - Main class
string responseBody = await response.Content.ReadAsStringAsync();
status.result deserializeObject = JsonConvert.DeserializeObject<status.result>(responseBody);
Debug.WriteLine(deserializeObject.SafeGasPrice.ToString());
Source Code - JSON Class
public class status
{
public class result
{
[JsonProperty(PropertyName = "SafeGasPrice")]
public int SafeGasPrice { get; set; }
[JsonProperty(PropertyName = "ProposeGasPrice")]
public int ProposeGasPrice { get; set; }
[JsonProperty(PropertyName = "FastGasPrice")]
public int FastGasPrice { get; set; }
}
}
Output
{"status":"1","message":"OK","result":{"LastBlock":"14296250","SafeGasPrice":"96","ProposeGasPrice":"96","FastGasPrice":"97","suggestBaseFee":"95.407119606","gasUsedRatio":"0.174721033333333,0.523179548504219,0.056945596868572,0.999939743363228,0.953861217484817"}}
0
Problem
I don't currently understand why a null is output, my guess is that I have implemented the json deserialization classes incorrectly.
Your data model does not correspond to the JSON provided, it is missing a type corresponding to the outer {"result": { }} object:
{
"status":"1",
"message":"OK",
"result":{
// This inner object corresponds to your model.
"LastBlock":"14296250",
"SafeGasPrice":"96",
"ProposeGasPrice":"96",
"FastGasPrice":"97",
"suggestBaseFee":"95.407119606",
"gasUsedRatio":"0.174721033333333,0.523179548504219,0.056945596868572,0.999939743363228,0.953861217484817"
}
}
To work around the problem, you need to introduce an outer, wrapper model. You could make an explicit one like so:
public class Root
{
public string status { get; set; }
public string message { get; set; }
public Result result { get; set; }
}
public class Result
{
[JsonProperty(PropertyName = "SafeGasPrice")]
public int SafeGasPrice { get; set; }
[JsonProperty(PropertyName = "ProposeGasPrice")]
public int ProposeGasPrice { get; set; }
[JsonProperty(PropertyName = "FastGasPrice")]
public int FastGasPrice { get; set; }
}
And deserialize like so:
var deserializeObject = JsonConvert.DeserializeObject<Root>(responseBody)?.result;
Or, you could use an anonymous type for the root model like so:
var deserializeObject = JsonConvert.DeserializeAnonymousType(responseBody, new { result = default(Result) })?.result;
Either way you will now be able to successfully deserialize the inner, nested properties.
So what did you do wrong? In your question, you declare result as a nested type:
public class status
{
public class result
{
[JsonProperty(PropertyName = "SafeGasPrice")]
public int SafeGasPrice { get; set; }
[JsonProperty(PropertyName = "ProposeGasPrice")]
public int ProposeGasPrice { get; set; }
[JsonProperty(PropertyName = "FastGasPrice")]
public int FastGasPrice { get; set; }
}
}
All this does is define a type result within the scope of another type status. It does not create a property named result within status. As there is no need for such nesting I recommend moving result out from inside status and renaming it Result to follow standard .NET naming conventions.
Demo fiddle here.
I want to serialize/deserialize the following JSON:
{
"result": {
"ID": 1,
"TITLE": "Example",
"ARRAY": [
{
"Item1": "Result1",
"Item2": "Result2"
}
]
}
}
I tried with the following class format, but no sucess yet... Can someone help me deserialize it?
public class myClass
{
public string ID { get; set; }
[JsonProperty("TITLE")]
public string Name { get; set; }
}
obs.: Using the namespace Newtonsoft.JSON
In your example class definition above, you have called the class myClass but you would have had to call it result because ID and TITLE are members of the result JSON in the given example. myClass would not resolve to anything.
I don't know why you'd want to have a property called Name that is mapped to TITLE, but ok, if you want to do that you can modify the solution after you get it working.
Still, we're not done yet. You also have a JSON member called ARRAY and you need to define a separate class for that.
And still there is an additional problem: the result JSON is nested inside an implicit base object, so we need to define that as well. Let's call it BaseResult.
public class ARRAY
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
public class Result
{
public int ID { get; set; }
public string TITLE { get; set; }
public List<ARRAY> ARRAY { get; set; }
}
public class BaseResult
{
public Result result { get; set; }
}
If you are using Visual Studio, you can copy your JSON and paste it in any *.cs file with Edit > Paste Special > Paste JSON as Classes. It will generate POCO objects representing your JSON, which in your case will be this:
public class Rootobject
{
public Result result { get; set; }
}
public class Result
{
public int ID { get; set; }
public string TITLE { get; set; }
public ARRAY[] ARRAY { get; set; }
}
public class ARRAY
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
Then, asuming that you have your JSON in a string variable named data, you can deserialize it as follows:
var result= JsonConvert.DeserializeObject<Rootobject>(data);
I'm trying to create multiple objects out of a JSON result.
My JSON looks like that:
EDIT
[{"quality":"hd","type":"video/mp4","width":1920,"height":1080,"link":"http://player.vimeo.com/external/255898412.hd.mp4?s=8766561d230749d75a0ddde2ddfbeb69e0e5198e&profile_id=175&oauth2_token_id=1040381751","created_time":"2018-02-15T15:46:25+02:00","fps":23.98,"size":3113207678,"md5":"b6beed65b699df870e481045178accc5","link_secure":"https://player.vimeo.com/external/255898412.hd.mp4?s=8766561d230749d75a0ddde2ddfbeb69e0e5198e&profile_id=175&oauth2_token_id=1040381751"},{"quality":"sd","type":"video/mp4","width":640,"height":360,"link":"http://player.vimeo.com/external/255898412.sd.mp4?s=b51b55f6bd6e1af2a8f48571e5804d91e6a82533&profile_id=164&oauth2_token_id=1040381751","created_time":"2018-02-15T15:46:05+02:00","fps":23.98,"size":536864946,"md5":"af227a5526af15d2bce6ac951d6cf06b","link_secure":"https://player.vimeo.com/external/255898412.sd.mp4?s=b51b55f6bd6e1af2a8f48571e5804d91e6a82533&profile_id=164&oauth2_token_id=1040381751"},{"quality":"sd","type":"video/mp4","width":960,"height":540,"link":"http://player.vimeo.com/external/255898412.sd.mp4?s=b51b55f6bd6e1af2a8f48571e5804d91e6a82533&profile_id=165&oauth2_token_id=1040381751","created_time":"2018-02-15T15:46:05+02:00","fps":23.98,"size":1242328160,"md5":"1963f908509b14fd7a40dc46bfa6c519","link_secure":"https://player.vimeo.com/external/255898412.sd.mp4?s=b51b55f6bd6e1af2a8f48571e5804d91e6a82533&profile_id=165&oauth2_token_id=1040381751"},{"quality":"hd","type":"video/mp4","width":1280,"height":720,"link":"http://player.vimeo.com/external/255898412.hd.mp4?s=8766561d230749d75a0ddde2ddfbeb69e0e5198e&profile_id=174&oauth2_token_id=1040381751","created_time":"2018-02-15T15:46:05+02:00","fps":23.98,"size":1977386604,"md5":"af38f067bd39f4f5bb71bad72f925337","link_secure":"https://player.vimeo.com/external/255898412.hd.mp4?s=8766561d230749d75a0ddde2ddfbeb69e0e5198e&profile_id=174&oauth2_token_id=1040381751"},{"quality":"hls","type":"video/mp4","link":"https://player.vimeo.com/external/255898412.m3u8?s=f25b7114977a0c6b37739886da189051ed31999e&oauth2_token_id=1040381751","created_time":"2018-02-15T15:46:25+02:00","fps":23.98,"size":3113207678,"md5":"b6beed65b699df870e481045178accc5","link_secure":"https://player.vimeo.com/external/255898412.m3u8?s=f25b7114977a0c6b37739886da189051ed31999e&oauth2_token_id=1040381751"}]
it should be parsed into 3 objects.
I got a VideoFileModel.cs class that looks like that:
public partial class VideoFileModel
{
[JsonProperty("quality")]
public string Quality { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("width")]
public long? Width { get; set; }
[JsonProperty("height")]
public long? Height { get; set; }
[JsonProperty("link")]
public string Link { get; set; }
[JsonProperty("created_time")]
public System.DateTime CreatedTime { get; set; }
[JsonProperty("fps")]
public double Fps { get; set; }
[JsonProperty("size")]
public long Size { get; set; }
[JsonProperty("md5")]
public string Md5 { get; set; }
[JsonProperty("link_secure")]
public string LinkSecure { get; set; }
}
What I'm trying to do at the moment, is parsing it like that:
string json = Helpers.HTTPFetch(url, method, headers, body, contentType);
var result = JsonConvert.DeserializeObject<VideoFileModel>(json);
but I'm pretty sure it's not working, or at least not in the way I want it to work.
what should I change?
You should simply use List<> when deserializing :
var result = JsonConvert.DeserializeObject<List<VideoFileModel>>(json);
There are is a list of VideoFileModel in your JSON that you trying to deserialize into a single object.
Following gets deserialized:
UPDATE:
As per OP updated JSON. It still gets deserialized:
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
// Deserialize the response to get an array of CUSTOM Cases
var reportsList = jsSerializer.Deserialize<SfdcObjects.SfdcCollection<SfdcObjects.Assets>>(HttpUtility.UrlDecode(response));
throws an exception:
Error: System.InvalidOperationException: Type 'SalesforceDataQueryComponent.Utils.SfdcObjects+SfdcCollection`1[
[SalesforceDataQueryComponent.Utils.SfdcObjects+Assets, SalesforceDataQueryComponent, Version=1.2.0.0, Culture=neutral]]'
is not supported for deserialization of an array.
I can not figure it out the issue:
Objects:
namespace SalesforceDataQueryComponent.Utils
{
class SfdcObjects
{
// Used for Authentication
public class TokenResponse
{
public string id { get; set; }
public string issued_at { get; set; }
public string refresh_token { get; set; }
public string instance_url { get; set; }
public string signature { get; set; }
public string access_token { get; set; }
}
// All classes shown next are used to parse the HttpGet Response
public class SfdcCollection<T>
{
public bool Done { get; set; }
public int Size { get; set; }
public string NextRecordsUrl { get; set; }
public List<T> Records { get; set; }
}
public class SfdcAttributes
{
public string Type { get; set; }
public string Url { get; set; }
}
public class Accounts : Account
{
public SfdcAttributes Attributes { get; set; }
}
public class Assets : Asset
{
public SfdcAttributes Attributes { get; set; }
}
public class CustomAssets : Assets
{
public string StringInstallDate { get; set; }
}
public class Users : User
{
public SfdcAttributes Attributes { get; set; }
}
public class CustomCase : Case
{
public string StringCreatedDate { get; set; }
}
public class CustomCases : CustomCase
{
public SfdcAttributes Attributes { get; set; }
}
}
}
You do not include your response JSON in your question, however from the error message, your problem must be that the root JSON container in your response is an array. A JSON array, according to the JSON standard, looks like this:
[value1, value2, ..., valueN]
JSON serializers map types that implement ICollection or IEnumerable from and to JSON arrays.
Your root object SfdcCollection<T>, however, is NOT a collection or enumerable, despite its name. Instead it's a non-enumerable generic POCO:
public class SfdcCollection<T> // No IEnumerable<T>
{
public bool Done { get; set; }
public int Size { get; set; }
public string NextRecordsUrl { get; set; }
public List<T> Records { get; set; }
}
Thus a serializer will map this to a JSON object (which is a set of key/value pairs and looks like {"name1" : value1, "name2" : value2, ..., "nameN" : valueN }) instead of an array.
You need to update your data model to the JSON you are actually receiving. Try uploading your JSON to http://json2csharp.com/, it will automatically generate classes for you.
If you must use the classes in your question, you could ask another question about how to map the JSON you are actually receiving onto your required classes, using your desired serializer (e.g. Json.NET, DataContractJsonSerializer, JavaScriptSerializer, or etc.)
I have the following c# model object
public class AddressUserFields
{
public string number { get; set; }
public string street { get; set; }
public string apartment { get; set; }
public string city { get; set; }
public string state { get; set; }
public string zipcode { get; set; }
public string DPV { get; set; }
}
When I am trying to convert it to json string using json serialization method, it will convert like the following,
JSON string: {userFields:[{"number":null,"street":null,"apartment":"","city":null,"state":null,"zipcode":null,"DPV":null}]}
But actually I look for like the below,
Expected JSON result:
{userFields:[{"number":null},{"street":null},{"apartment":""},{"city":null},{"state":null},{"zipcode":null},{"DPV":null}]}
So could any one give the way to design my c# model object and get the expected json result.
You just have to create your poco objects in the structure your want the Json to be in.
If you want this structure:
{userFields:
[
{ "number":null,
"street":null,
"apartment":"",
"city":null,
"state":null,
"zipcode":null,
"DPV":null
}
]
}
This is an object with one property userFields of type AddressUserFields[].
So just add another class
public class SomeContainer
{
public AddressUserFields[] userFields {get;set;}
}
and serialize that one
If you really want an array of different objects which all have different properties, like what you posted:
...[{"number":null},{"street":null},{"apartment":""},...]
you can use an array of Dictionary<TKey,TValue>, like this:
public class Fields
{
public Dictionary<string, string>[] userFields { get; set; }
}
and use it like so?
var fields = new Fields()
{
userFields = new[]{
new Dictionary<string,string>(){{"number", null}},
new Dictionary<string,string>(){{"street", null}}
}
};
var json = JsonConvert.SerializeObject(fields);