Hi I having following JSON but while Using Deserialize method getting NULL in nested Member here is the sample JSON and corresponding Class object:
{
"status": "success",
"Info": [
{
"Name": "1099589",
"version": "Current Version",
"MoreDetails": [
{
"Name": "1099589",
"state": "IN"
},
{
"Name": "1099768",
"state": "OUT"
}
]
},
{
"Name": "1099768",
"version": "2019"
}
],
"errorCode": "",
"message": ""
}
Class :
public class MoreDetail
{
public string Name { get; set; }
public string state { get; set; }
}
public class Info
{
public string Name { get; set; }
public string version { get; set; }
public IList<MoreDetail> MoreDetails { get; set; }
}
public class Example
{
public string status { get; set; }
public IList<Info> Info { get; set; }
public string errorCode { get; set; }
public string message { get; set; }
}
While I am using
JavaScriptSerializer js = new JavaScriptSerializer();
Example ex = new OfferingPayload();
ex = js.Deserialize<Example> (jsonstring);
I am able to see Example object having Info data as list but MoreDetails member of Info Class is coming NULL.
Can someone suggest what I am missing here ?
Thats because your second "Info" object doesnt have "MoreDetails" property.
{
"Name": "1099768",
"version": "2019"
}
To make it works you can add an empty "MoreDetails" property to your json.
{
"Name": "1099768",
"version": "2019",
"MoreDetails": []
}
Or you can configure your serializer to handle this property as optional. Then it will works fine even if it missing in your json.
Related
I want to retrieve the list of Booking collection.
Some of the collection have,
Case 1
"Countries": [{
"Destinations": [{
"Code": "CHX",
"Name": "French Alps"
}],
"Code": {
"_t": "JsonElement"
},
"Name": {
"_t": "JsonElement"
}
}]
and some of them have,
Case 2
"Countries": [{
"Destinations": [{
"Code": "DXB",
"Name": "Dubai"
}],
"Code": "AE",
"Name": "United Arab Emirates"
}]
Note that code and name fields.
and the model for retrieve list is
{
public List<DestinationDocument> Destinations { get; set; } = new List<DestinationDocument>();
public string Code { get; set; }
public string Name { get; set; }
}
I want to to ignore the code and name when they are not string (i.e I want to ignore code and name of case 1 . but not Destinations of case 1 ).
How can I do that using mongoDb driver.
I tried SetIgnoreExtraElements. but it does not work.
Easiest way to control the way MongoDB .NET deserializes your data is probably to create your own serializer and return null whenever it encounters anything different than BsonType.String. It can be done in two steps. Define your custom deserialization logic:
public class IgnoreDocumentSerializer : SerializerBase<string>
{
public override string Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var serializer = BsonSerializer.LookupSerializer(typeof(string));
if(context.Reader.CurrentBsonType == BsonType.String)
{
return (string)serializer.Deserialize(context, args);
}
if (context.Reader.CurrentBsonType == BsonType.Document)
{
context.Reader.ReadRawBsonDocument();
}
return null;
}
}
and decorate your model properties with BsonSerializer attribute:
public class Country
{
public List<DestinationDocument> Destinations { get; set; } = new List<DestinationDocument>();
[BsonSerializer(typeof(IgnoreDocumentSerializer))]
public string Code { get; set; }
[BsonSerializer(typeof(IgnoreDocumentSerializer))]
public string Name { get; set; }
}
ok so im not entirely sure how to explain this but ill give it my best shot. i have deserialisation from json working on singular objects, but when i get a list of the objects in json form, it doesnt work, and there are a few extra details outside of the singular objects when in a list of the objects.
the line of code im pretty sure is the problem is
var model = JsonConvert.DeserializeObject<DeserializedObjects.BlockList>(JObject.Parse(json).ToString());
but i cannot figure out how to solve it.
anyway.
this is where the multiple data objects in json from come from:
public static async Task<DeserializedObjects.BlockList> GetUpToTenBlocks(int height)
{
var JData = (dynamic)new JObject();
JData.height = height;
String uri = String.Concat(partialApi, "/local/chain/blocks-after");
var response = await client.PostAsync(uri, new StringContent(JData.ToString(), Encoding.UTF8, "application/json"));
var content = response.Content;
{
var json = await content.ReadAsStringAsync();
var model = JsonConvert.DeserializeObject<DeserializedObjects.BlockList>(JObject.Parse(json).ToString());
Console.WriteLine(model.AtIndex[1].difficulty);
return model;
}
}
which is deserialized to:
public class PrevBlockHash
{
public string data { get; set; }
}
public class Block
{
public int timeStamp { get; set; }
public string signature { get; set; }
public PrevBlockHash prevBlockHash { get; set; }
public int type { get; set; }
public List<object> transactions { get; set; }
public int version { get; set; }
public string signer { get; set; }
public long height { get; set; }
}
public class Datum
{
public object difficulty { get; set; }
public List<object> txes { get; set; }
public Block block { get; set; }
public string hash { get; set; }
}
public class BlockList
{
public List<Datum> AtIndex { get; set; }
}
and this is the json payload:
{
"data": [
{
"difficulty": 11763927507942,
"txes": [],
"block": {
"timeStamp": 167479,
"signature": "bb062d9b5f132b39b9e56de2413bf04928af009587446621da7afd351d
15a2ce7b5504450acf41bc3b19ab71e9bf34722005239d93f05a2318130f85118df40c",
"prevBlockHash": {
"data": "d4875ad2fc74dacfa89a13f24159d14555d3766f4fe2d708a7596f84eba88
31b"
},
"type": 1,
"transactions": [],
"version": 1744830465,
"signer": "00a30788dc1f042da959309639a884d8f6a87086cda10300d2a7c3a0e0891
a4d",
"height": 1001
},
"hash": "f70898011d7343a0823de9c9cf263de29ddf2c16bb78cea626b9af90ea7ec260"
},
{
"difficulty": 11625594628802,
"txes": [],
"block": {
"timeStamp": 167561,
"signature": "116dedf43dd06b9ca634db0e20e06cc93337cdba155bced4d843ece4cc
9a57487d58e9a34d8a0e19bf71d3b7facb15179a87767f0063ebbce7c940cd545d5f01",
"prevBlockHash": {
"data": "f70898011d7343a0823de9c9cf263de29ddf2c16bb78cea626b9af90ea7ec
260"
},
"type": 1,
"transactions": [],
"version": 1744830465,
"signer": "6ecd181da287c9ccb0075336de36427f25cbc216dc6b1f0e87e35e41a39f6
3fe",
"height": 1002
},
"hash": "77b5644c35e0d0d51f8bb967d0d92e0ddb03c4ede6632cb3b7651b7394617562"
},
{
"difficulty": 11538802895169,
"txes": [],
"block": {
"timeStamp": 167624,
"signature": "982574132fdc99b6f484acdd3f1cb5229b2bf78ad7b4e9af3d7a1873da
b987401f8bf808ff749aca70c503f490db1411b6cd89dbb0c1daa24fd580f91d3d9601",
"prevBlockHash": {
"data": "77b5644c35e0d0d51f8bb967d0d92e0ddb03c4ede6632cb3b7651b7394617
562"
},
"type": 1,
"transactions": [],
"version": 1744830465,
"signer": "26a3ac4b24647c77dc87780a95e50cb8d7744966e4569e3ac24e52c532c0c
d0d",
"height": 1003
},
"hash": "1a6d52c6317150d1839790da2c1481d714038c869842f769affbec0fdeec9861"
}
]
}
Try this:
var model = JsonConvert.DeserializeObject<DeserializedObjects.BlockList>(json);
Console.WriteLine(model.data[1].difficulty);
along with, also:
public class BlockList
{
public List<Datum> data { get; set; }
}
I have a salesforce rest service which returns results in IEnumerable format. Below is a sample results.
[{
"attributes": {
"type": "Account",
"url": "/services/data/v28.0/sobjects/Account/001i0000WK5xYAAT"
},
"RecordType": {
"attributes": {
"type": "RecordType",
"url": "/services/data/v28.0/sobjects/RecordType/012i00000x7FwAAI"
},
"Name": "Health Care Practitioners"
},
"Name": "JOSEPH SANDERS",
"Status_ims__c": "Verified",
},
{
"attributes": {
"type": "Account",
"url": "/services/data/v28.0/sobjects/Account/001i000000WK5xYAAT"
},
"RecordType": {
"attributes": {
"type": "RecordType",
"url": "/services/data/v28.0/sobjects/RecordType/012i0000000x7FwAAI"
},
"Name": "Health Care Practitioners"
},
"Name": "DONALD GRABER",
"Status_ims__c": "Verified",
}]
public class Account
{
public string Name { get{ return GetOption ("Name");} }
public string Status_ims__c { get{ return GetOption ("Status_ims__c");}}
public Attributes attributes {get;}
public RecordType recordType {get;}
}
public class Attributes
{
public string type { get; set; }
public string url { get; set; }
}
public class Attributes2
{
public string type { get; set; }
public string url { get; set; }
}
public class RecordType
{
public Attributes2 attributes { get; set; }
public string Name { get; set; }
}
Above is the structure I have for Account Object. How to convert results to List and map to each property on Account object.
For Example is using json.net ->
var account = JsonConvert.DeserializeObject<List<Account>>(stringData);
Also if there are some differences between the object and the data you can use JsonProperty Annotations
Therefore you could also have more readable properties in your class model like
[JsonProperty("Status_ims__c ")]
public string Status
You can simple use this:
var accounts = JsonConvert.DeserializeObject<List<Account>>("your json string...");
If you use Newtonsoft.Json you can use Newtonsoft.Json.JsonConvert.DeserializeObject method.
Also make sure that your properties have setters in Account class.
Okay first of all, the answer is probably very simple... But after 45 minutes of trying and googling I just can't figure it out!
So I have some problems getting this Json to parse correctly. I created the classes with http://json2csharp.com/ only it doesn't tell me the code to parse it.
My current classes:
public class Representations
{
public string thumb { get; set; }
public string large { get; set; }
public string full { get; set; }
}
public class Search
{
public string id { get; set; }
public string file_name { get; set; }
public Representations representations { get; set; }
}
public class SearchQuery
{
public List<Search> search { get; set; }
public int total { get; set; }
}
JSON:
{
"search": [
{
"id": "0300",
"file_name": "0300.JPG",
"representations": {
"thumb": "thumb.jpg",
"large": "large.jpg",
"full": "0300.jpg"
},
},
{
"id": "0000",
"file_name": "0000.JPG",
"representations": {
"thumb": "thumb.jpg",
"large": "large.jpg",
"full": "0000.jpg"
},
},
{
"id": "0d00",
"file_name": "0d00.JPG",
"representations": {
"thumb": "thumb.jpg",
"large": "large.jpg",
"full": "0d00.jpg"
},
}
],
"total": 3
}
and code:
searchresults = JsonConvert.DeserializeObject<List<SearchQuery>>(JSONCode);
You should deserialize to a SearchQuery, not List<SearchQuery>:
SearchQuery result = JsonConvert.DeserializeObject<SearchQuery>(JSONCode);
and then use the search property to access the list of search results:
List<Search> searchResults = result.search;
I am using System.Net.Http.HttpClient, the version currently available in NuGet,
to retrieve data from a service in json format. The data roughly looks like this:
{
"schema": "Listing",
"data": {
"key": "28ba648c-de24-45d4-a7d9-70f810cf5438",
"children": [{
"kind": "type1",
"data": {
"body": "Four score and seven years ago...",
"parent_id": "2qh3l",
"report_count": 0,
"name": "c4j6yeh"
}
}, {
"kind": "type3",
"data": {
"domain": "abc.def.com",
"flagged": true,
"category": "news",
"saved": false,
"id": "t3dz0",
"created": 1335998011.0
}
}]
}
}
I use HttpContentExtensions.ReadAsAsync<T> to de-serialize that json string into an object graph. The type definitions looks roughly like this:
public class Response
{
public String schema { get;set; }
public ListingData data { get;set; }
}
public class ListingData
{
public string key { get;set; }
public List<OneItem> children { get;set; }
}
Here's the problem: I desire the type of the items in children to vary depending on the kind property. If kind is "type1" then I want to de-serialize an object of... let's call it Type1 . If kind is "type3" then I want an object of type Type3.
Right now, I can deserialize a List<Type1> or a List<Type3>, but I don't know how to tell the de-serialization logic to distinguish between the two.
I could merge all the properties of the "type1" data object and the "type3" data object into a single .NET Type. But the number of properties is large enough that this gets messy.
If the name of the property in the JSON (in this case data) were different, I could distinguish using that. If, for example, the data looked like this:
"children": [{
"kind": "type1",
"t1data": { ... }
}, {
"kind": "type3",
"t3data": { ... }
}]
...then I could do something like this in .NET:
public class OneItem
{
public string kind { get;set; }
public Type1 t1data { get;set; }
public Type3 t3data { get;set; }
}
But my data schema doesn't look like that.
Is it possible to choose the type for de-serialization by the content of the data? In other words,
look at the value of one property (in this case, kind) to determine how to de-serialize the content for another property (in this case, data).
Or is it possible to inject a filter or transformer that acts on the JSON before ReadAsAsync tries to deserialize it?
If so, How?
If you're ok w/ doing some pre-processing on your response and you can use Json.NET, you should be able to do what you want.
Given the following classes:
public class Response
{
public string schema
{
get;
set;
}
public ListingData data
{
get;
set;
}
}
public class ListingData
{
public string key
{
get;
set;
}
public List<object> children
{
get;
set;
}
}
public class Type1
{
public string body
{
get;
set;
}
public string parent_id
{
get;
set;
}
public int report_count
{
get;
set;
}
public string name
{
get;
set;
}
}
public class Type3
{
public string domain
{
get;
set;
}
public bool flagged
{
get;
set;
}
public string category
{
get;
set;
}
public bool saved
{
get;
set;
}
public string id
{
get;
set;
}
public double created
{
get;
set;
}
}
This test passes:
[Test]
public void RoundTrip()
{
var response = new Response
{
schema = "Listing",
data = new ListingData
{
key = "28ba648c-de24-45d4-a7d9-70f810cf5438",
children = new List<object>
{
new Type1
{
body = "Four score and seven years ago...",
parent_id = "2qh3l",
report_count = 0,
name = "c4j6yeh"
},
new Type3
{
domain = "abc.def.com",
flagged = true,
category = "news",
saved = false,
id = "t3dz0",
created = 1335998011.0
}
}
}
};
var jsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Objects
};
string serializedResponse = JsonConvert.SerializeObject(response, jsonSerializerSettings);
Console.WriteLine(serializedResponse);
var roundTrippedResponse = JsonConvert.DeserializeObject<Response>(serializedResponse, jsonSerializerSettings);
Assert.That(roundTrippedResponse.data.children.First().GetType(), Is.EqualTo(typeof(Type1)));
Assert.That(roundTrippedResponse.data.children.Last().GetType(), Is.EqualTo(typeof(Type3)));
}
The output written to the console is:
{
"$type": "Test.Response, Test",
"schema": "Listing",
"data": {
"$type": "Test.ListingData, Test",
"key": "28ba648c-de24-45d4-a7d9-70f810cf5438",
"children": [
{
"$type": "Test.Type1, Test",
"body": "Four score and seven years ago...",
"parent_id": "2qh3l",
"report_count": 0,
"name": "c4j6yeh"
},
{
"$type": "Test.Type3, Test",
"domain": "abc.def.com",
"flagged": true,
"category": "news",
"saved": false,
"id": "t3dz0",
"created": 1335998011.0
}
]
}
}
So if you can transform your received response to match that of Json.NET's expected format, this will work.
To piece all of this together, you would need to write a custom MediaTypeFormatter and pass it to the ReadAsAsync<>() call.