I am fetching a Json object which has a Details field that is an array of Detail objects, for example:
"details":"[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},{\"field_id\":\"72403497\",\"response\":\"\",\"field_type\":\"text\"},{\"field_id\":\"845605582\",\"response\":\"Michael\",\"field_type\":\"text\"},{\"field_id\":\"987024660\",\"response\":\"157\",\"field_type\":\"dropdown\"}]"
The model I have for the Details field is:
[JsonProperty("details")]
public List<LogDetailModel> DetailModels { get; set; }
And the Detail object model is:
[JsonProperty("field_id")]
public string EditedFieldId { get; set; }
[JsonProperty("response")]
public string Response { get; set; }
[JsonProperty("field_type")]
public string FieldType { get; set; }
However, when I try to deserialize the results (an array of my base model), I get the following:
JsonSerializationException: Error converting value "[{"field_id":"1142488407","response":"256","field_type":"text"},{"field_id":"72403497","response":"","field_type":"text"},{"field_id":"845605582","response":"Michael","field_type":"text"},{"field_id":"987024660","response":"157","field_type":"dropdown"}]" to type 'System.Collections.Generic.List`1[KolHalev.Business.Breeze.Models.LogDetailModel]'. Path '[0].details', line 1, position 423.
And if I instead fetch that field as a string, and then deserialize thusly:
[JsonProperty("details")]
public string Details { get; set; }
public List<LogDetailModel> DetailModels { get { return JsonConvert.DeserializeObject<List<LogDetailModel>>(Details); } }
This works fine. What am I missing?
The reason why you could not deserialize it directly is because your json and your data model has a mismatch.
"details":"[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},..]"
In this case your details data type is string
So, you can NOT parse it directly as a collection of objects
if your json would look like this:
"details":[{\"field_id\":\"1142488407\",\"response\":\"256\",\"field_type\":\"text\"},..]
the the data type of the details field would be a collection
So, the very reason why did your second approach worked is because you have first deserialized the details then you deserialized the json array.
try this
Details details = JsonConvert.DeserializeObject<Details>(json);
//Or more flexible
//Detail details = new Details
//{
// DetailsString = (string)JObject.Parse(json)["details"]
//};
classes
public class Details
{
[JsonProperty("details")]
public string DetailsString { get; set; }
public List<LogDetailModel> DetailModels { get { return JsonConvert.DeserializeObject<List<LogDetailModel>>(DetailsString); } }
}
public class LogDetailModel
{
[JsonProperty("field_id")]
public string EditedFieldId { get; set; }
[JsonProperty("response")]
public string Response { get; set; }
[JsonProperty("field_type")]
public string FieldType { get; set; }
}
Related
This line is giving me the error
Cannot deserialize the current JSON object (e.g. {"name":"value"})
From other posts I gather I should not be putting this into a list. However This worked fine for me until I added the avgPx field.
How can I get this information into my List properly?
Does my list of type <OrderRecord> need to include all the fields returned by the JSON?
List<OrderRecord> orderRecord_Single = new List<OrderRecord>();//define and set to null
OrderRecord_Single = JsonConvert.DeserializeObject<List<OrderRecord>>(orderString);
This is one case of my jsonstring. It has the brackets on it.
"[{\"orderID\":\"5dcc6560-9672-958d-010b-7d18c9d523ab\",\"account\":1024235,\"symbol\":\"ETHUSD\",\"timestamp\":\"2020-04-26T18:21:05.703Z\",\"clOrdID\":\"\",\"side\":\"Buy\",\"price\":194.95,\"orderQty\":1,\"ordStatus\":\"New\",\"text\":\"ZT\",\"transactTime\":\"2020-04-26T18:21:05.703Z\",\"avgPx\":null}]"
public class OrderRecord
{
[JsonProperty("orderID")]
public string orderID { get; set; }
[JsonProperty("symbol")]
public string symbol { get; set; }
[JsonProperty("side")]
public string side { get; set; }
[JsonProperty("price")]
public string price { get; set; }
[JsonProperty("orderQty")]
public string orderQty { get; set; }
[JsonProperty("ordStatus")]
public string ordStatus { get; set; }
[JsonProperty("transactTime")]
public string transactTime { get; set; }
[JsonProperty("timestamp")]
public string timestamp { get; set; }
[JsonProperty("avgPx")]
public string avgPx { get; set; }
}
The error occurs because you are trying deserializing a JSON object to a JSON array. So you should provide a JSON array as in input. For the given JSON, add brackets [ ] to the first and last of the JSON string for creating valid JSON array:
var jsonString = "[{\"orderID\":\"8d853505-248d-e515-ee17-ddcd24b5fecb\",\"account\":1024235,\"symbol\":\"XBTUSD\",\"timestamp\":\"2020-04-20T18:25:07.601Z\",\"clOrdID\":\"\",\"side\":\"Buy\",\"price\":6885.5,\"orderQty\":8700,\"ordStatus\":\"Filled\",\"text\":\"ZT\",\"transactTime\":\"2020-04-20T18:22:11.135Z\",\"avgPx\":6885.5}]"
I have JSON string results as follows.
In this response Sometimes sizeKey and sizeName properties are returned as a string. But sometimes both properties are returns inside an array as follows
I am using following code to convert it to object
var assets = jObject["assets"].Children().ToList();
foreach (var item in assets)
{
decorationAssets.Add(item.ToObject<AEDecorationAssets>());
}
And my AEDecorationAssets class is as follows.
public class AEDecorationAssets
{
public string Id { get; set; }
public string Url { get; set; }
public string[] Colors { get; set; }
public string FontKey { get; set; }
public string SizeKey { get; set; }
public string ViewKey { get; set; }
public string FontName { get; set; }
public int Rotation { get; set; }
public string SizeName { get; set; }
public string TextValue { get; set; }
public string EntityType { get; set; }
public string LocationCode { get; set; }
public string LocationName { get; set; }
public string TextEffectKey { get; set; }
public string TextEffectName { get; set; }
public string DecorationMethod { get; set; }
public string NumDecorationColors { get; set; }
}
At the time when "sizeKey" is an array, the above code gives an error. How can I resolve this issue? Is there any JSON property we can use to resolve it?
One way you can do it is by making your SizeKey type an object (i.e. public object SizeKey { get; set; }), then you can switch/case on item.ToObject<AEDecorationAssets>().SizeKey.GetType() to figure out how to handle it (i.e. if String do this, if JArray do that), etc.
If a JSON type is sometime an array, and sometimes a string, you can't really map it simply to a .NET type, as there is none that supports this behavior.
So first you need a datatype that can store this, like and string[] or List<string>.
It could be that JsonConvert will solve this automatically, but otherwise you'll need to write a custom ContractResolver or JsonConverter. Here you can detect if the source property is a string or array. If it's an array, you can use the default deserialization. If it is a string, you need to convert it to an array with a single value.
Simply get json result for which you want to create c# object and then you can valid json response from https://jsonlint.com/ and then you can create c# object of any type json response which you want through http://json2csharp.com. And after get c# object of your json response you only need to deserialization of your json response to c# object which you have created. which will return you expected result.
How do I deserialize json string to object depends on json content?
I would like to do this with Newtonsoft.Json, since I am using it in the whole project and it is simple for use.
Let me explain by example:
I have json string which can have to be different property object. Content depends on the tool that generates the json files, and I cannot predict the content base on the filename or something like that.
For example, I can have json file:
{
"FileCreationDate":"29-08-2018 14:56:30",
"MessageType":2,
"Messages":[
{
"MessageSequenceNumber":1,
"ModalType":5,
"Message":{
"TransactionValue":5,
"ProductAmount":5
}
}
]
}
Or I can have something like this:
{
"FileCreationDate":"29-08-2018 14:56:30",
"MessageType":1,
"Messages":[
{
"MessageSequenceNumber":1,
"ModalType":5,
"Message":{
"TransactionBusinessDate":"29-08-2018 14:54:29",
"TransactionStatus":5,
"TicketNumber":5,
}
}
]
}
You can see that both json strings have same properties except message object in messages list.
I want to deserialize to this data structure:
public class EventFileDto
{
public string FileCreationDate { get; set; }
public MessageType MessageType { get; set; }
public IEnumerable<MessageDetailsDto> Messages { get; set; }
}
public class MessageDetailsDto
{
public int MessageSequenceNumber { get; set; }
public int ModalType { get; set; }
public EventMessageDto EventMessage { get; set; }
public TransactionMessage TransactionMessage { get; set; }
}
If json string is from the first example I want deserialize message object to EventMessage property, and TransactionMessage property should be null.
In the case of second json string, I want the opposite.
I don't want use dynamic type, since mapping to the entity would be more complicated.
How can this be done?
Thank you for your help.
I am getting JSON that is being returned from a REST web service for survey responses. It has arrays for the name portion of some of the name value pairs. Additionally the names will be variable depending on the type of questions asked. I'm using JSON.net and trying to deserialize the returned value into some type of object tree that I can walk but can't figure out what structure to use to have it filled in.
I tested the following snippet in LinqPad and fields is always empty. Is there someway to easily read in the variable data or do I have to parse it in code?
void Main() {
string json = #"{
'result_ok':true,
'total_count':'51',
'data':[{
'id':'1',
'status':'Deleted',
'datesubmitted':'2015-01-12 10:43:47',
'[question(3)]':'Red',
'[question(4)]':'Blue',
'[question(18)]':12,
'[variable(\'STANDARD_IP\')]':'127.0.0.1',
'[variable(\'STANDARD_GEOCOUNTRY\')]':'United States'
}]
}";
var responses = JsonConvert.DeserializeObject<RootObject>(json);
responses.Dump();
}
public class RootObject {
public bool result_ok { get; set; }
public string total_count { get; set; }
public List<Response> data { get; set; }
}
public class Response {
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
public List<object> fields = new List<object>();
}
Change the fields property in your Response class to be a Dictionary<string, object>, then mark it with a [JsonExtensionData] attribute like this:
public class Response
{
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
[JsonExtensionData]
public Dictionary<string, object> fields { get; set; }
}
All of the fields with the strange property names will then be placed into the dictionary where you can access them as normal. No extra code is required.
Here is a demo: https://dotnetfiddle.net/1rQUXT
I am trying to Deserialize (using Newtonsoft) JSON and convert to List in c#. It is throwing me error " Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[obJson]'."
Here is my JSON string:
string webContent = "{\"searchResults\": [{\"gefId\":0,\"resultNumber\":1,\"distance\":4.2839,\"sourceName\":\"MQA.MQ_34172_HD\",\"name\":\"USER_DEFINED\"},{\"gefId\":0,\"resultNumber\":1,\"distance\":4.2839,\"sourceName\":\"MQA.MQ_34172_HD\",\"name\":\"USER_DEFINED\"}]}";
Conversion, this line is throwing error:
List<obJson> result = JsonConvert.DeserializeObject<List<obJson>>(webContent);
My custom classes:
public class SearchResults
{
public int gefId { get; set; }
public int resultNumber { get; set; }
public decimal distance { get; set; }
public string sourceName { get; set; }
public string name { get; set; }
}
public class obJson
{
public SearchResults SearchResults { get; set; }
}
Since your json is an object whose searchResults member contains an array, change your obJson as below
public class obJson
{
public List<SearchResults> searchResults { get; set; }
}
and deserialize as
obJson result = JsonConvert.DeserializeObject<obJson>(webContent);
The problem is with your model or conversely with data you are sending. You are receiving an array and hoping to deserialize it into plain object. You can change your model like
public class obJson
{
public SearchResults[] SearchResults { get; set; }
}
and your result will be deserialized just fine.
your json is not valid.
Parse error on line 1:
{ \"searchResults\": [
-----^
Expecting 'STRING', '}'
http://jsonlint.com/