Issues with deserializing Json in C# - c#

I have some json like this:
{
"status": "OK",
"result": {
"#type": "address_result__201301",
"barcode": "1301013030001010212212333002003031013",
"bsp": "044",
"dpid": "99033785",
"postcode": "4895",
"state": "QLD",
"suburb": "COOKTOWN",
"city": null,
"country": "AUSTRALIA"
},
"search_date": "03-12-2014 15:31:03",
"search_parameters": {},
"time_taken": 636,
"transaction_id": "f8df8791-531e-4043-9093-9f35881f6bb9",
"root_transaction_id": "a1fa1426-b973-46ec-b61b-0fe5518033de"
}
Then I created some classes:
public class Address
{
public string status { get; set; }
public Result results { get; set; }
public string search_date { get; set; }
public SearchParameters search_parameters { get; set; }
public int time_taken { get; set; }
public string transaction_id { get; set; }
public string root_transaction_id { get; set; }
}
public class Result
{
public string #type { get; set; }
public string barcode { get; set; }
public string bsp { get; set; }
public string dpid { get; set; }
public string postcode { get; set; }
public string state { get; set; }
public string suburb { get; set; }
public string city { get; set; }
public string country { get; set; }
}
public class SearchParameters
{
}
Finally, I use these code to get Json data:
string result = "Above json";
JavaScriptSerializer json = new JavaScriptSerializer();
Address add = json.Deserialize<Address>(result);
I see that, add.status, add.search_date... etc have values, but add.results is null.
What is wrong with my code?

I think the issue is using #type as illegal identifier. Try using [DataMember(Name = "#type")] before public string #type { get; set; }. Add a [DataContract] before public class Address.
Hence, your final code will be,
[DataContract]
public class Result
{
[DataMember(Name = "#type")]
public string #type { get; set; }
public string barcode { get; set; }
public string bsp { get; set; }
public string dpid { get; set; }
public string postcode { get; set; }
public string state { get; set; }
public string suburb { get; set; }
public string city { get; set; }
public string country { get; set; }
}

Related

Deserialize Complex/Branched JSON and accessing branches

I have a JSON response which i generated a model from. the JSON data has various branches with data as shown below.
{
"error": false,
"result": {
"customers": [
{
"district": null,
"feeder": "XXXXXXXXXXX",
"feeder_code": "XXXXXXXXXXX",
"transformer": "XXXXXXXXXXX",
"dss_code": "XXXXXXXXX",
"database_match": "XXXXXXXXXXX",
"accountnumber": "XXXXXXXXXXX",
"meterno": "XXXXXXXXXXX",
"oldaccountnumber": "XXXXXXXXXXX",
"odoo_account_number": "XXXXXXXXXXX",
"customername": "XXXXXXXXXXX",
"address": "XXXXXXXXXXX",
"phone": "",
"tarrif": "XXX",
"tariff_category": "NON-MD",
"service_band": "C ",
"status": "Active",
"status_period": "MAY",
"payment_status": null,
"arrears": "29431.78",
"long_x": "7.0385020000",
"lat_y": "5.4909420000",
"transactional_details": {
"queryresult": {
"responseMessage": "success",
"customer": {
"accountNumber": "XXXXXXXXXXX",
"meterNumber": "XXXXXXXXXXX",
"phoneNumber": "",
"lastName": "XXXXXXXXXXX",
"address": "XXXXXXXXXXX",
"city": "XXXXXXXXXXX",
"district": "Owerri",
"userCategory": "NON-MD",
"customerType": "metered",
"paymentPlan": "Prepaid",
"vat": 0,
"tariffCode": "R2SC-NMD",
"tariffRate": 52.6,
"arrearsBalance": 0,
"billedAmount": 0,
"billedDate": null,
"lastPayDate": "2021-09-21 12:16:46",
"lastpayment": {
"transactionRef": "88099064",
"units": 0,
"transactionDate": "JXXXXXXXXXXX",
"transactionId": "XXXXXXXXXXX",
"transactionBookId": 0,
"amountPaid": 1000,
"mscPaid": 0,
"invoiceNumber": "17289583"
}
},
"responseCode": 200,
"status": "true"
},
"status": true
}
}
],
"row_count": 2
}
}
I have various branches in this JSON response which i need to use. i generated a model class from this JSON as shown below
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Customer
{
public object district { get; set; }
public string feeder { get; set; }
public string feeder_code { get; set; }
public string transformer { get; set; }
public string dss_code { get; set; }
public string database_match { get; set; }
public string accountnumber { get; set; }
public string meterno { get; set; }
public string oldaccountnumber { get; set; }
public string odoo_account_number { get; set; }
public string customername { get; set; }
public string address { get; set; }
public string phone { get; set; }
public string tarrif { get; set; }
public string tariff_category { get; set; }
public string service_band { get; set; }
public string status { get; set; }
public string status_period { get; set; }
public object payment_status { get; set; }
public string arrears { get; set; }
public string long_x { get; set; }
public string lat_y { get; set; }
public TransactionalDetails transactional_details { get; set; }
}
public class Customer2
{
public string accountNumber { get; set; }
public string meterNumber { get; set; }
public string phoneNumber { get; set; }
public string lastName { get; set; }
public string address { get; set; }
public string city { get; set; }
public string district { get; set; }
public string userCategory { get; set; }
public string customerType { get; set; }
public string paymentPlan { get; set; }
public int vat { get; set; }
public string tariffCode { get; set; }
public double tariffRate { get; set; }
public int arrearsBalance { get; set; }
public int billedAmount { get; set; }
public object billedDate { get; set; }
public string lastPayDate { get; set; }
public Lastpayment lastpayment { get; set; }
}
public class Lastpayment
{
public string transactionRef { get; set; }
public int units { get; set; }
public string transactionDate { get; set; }
public string transactionId { get; set; }
public int transactionBookId { get; set; }
public int amountPaid { get; set; }
public int mscPaid { get; set; }
public string invoiceNumber { get; set; }
}
public class Queryresult
{
public string responseMessage { get; set; }
public Customer customer { get; set; }
public int responseCode { get; set; }
public string status { get; set; }
}
public class Result
{
public ObservableCollection<Customer> customers { get; set; }
public int row_count { get; set; }
}
public class Root
{
public bool error { get; set; }
public Result result { get; set; }
}
public class TransactionalDetails
{
public Queryresult queryresult { get; set; }
public bool status { get; set; }
}
Afterwards i used the C# code to deserialize the JSON as shown below
Root myroot = JsonConvert.DeserializeObject<Root>(readTask);
ObservableCollection<Customer> data = myroot.result.customers;
This works fine, however, i am stuck with just customer Data. I want to be able to get the Transactional details (Customer2) and Lastpayment branches in a collection view. how can i achieve this? Thanks
You can parse your json and read it by linq. ToObject method help you to convert nodes to specific class.
I have taken json text in InputJson variable and then paresed it.
var parsed = JObject.Parse(InputJson);
var innerNodes = JArray.Parse(parsed["result"]["customers"].ToString());
var CustomerList = innerNodes.Select(x => x.ToObject<Customer>()).ToList();
And if you need just some of properties you can use in this way
var CustomerList = innerNodes.Select(x =>
new Customer
{
district = x["district"],
feeder = x["feeder"].ToString(),
transactional_details =x["transactional_details"].ToObject<TransactionalDetails>()
})
.ToList();
If you have different nodes in your object , you can call nodes and check them not be null!
var CustomerList = innerNodes.Select(x => new
{
district = x["district"],
feeder = x["feeder"].ToString(),
transactional_details =x["transactional_details"]?.ToObject<TransactionalDetails>(),
Lastpayment = x["transactional_details"]?["queryresult"]?["customer"]?["lastpayment"]?.ToObject<Lastpayment>(),
billedAmount = x["transactional_details"]?["queryresult"]?["customer"]?["billedAmount"] ?.ToString()
}).ToList();
Customers is an array object so you must iterate through this array.
For example this would work:
Root myroot = JsonConvert.DeserializeObject<Root>(json);
myroot.result.customers.ToList().ForEach(c =>
{
Console.WriteLine(c.transactional_details.queryresult.customer.lastpayment.amountPaid);
});
Looking at Locals in vs debugger for
var customers = myroot.result.customers.ToList();
we get this:
fix Queryresult class by changing Customer to Customer2
public class Queryresult
{
public string responseMessage { get; set; }
public Customer2 customer { get; set; }
public int responseCode { get; set; }
public string status { get; set; }
}
now you can get a lastpayment
Root myroot = JsonConvert.DeserializeObject<Root>(readTask);
LastPayment lastPayment = myroot.result.customers
.Select(c=>c.transactional_details.queryresult.customer.lastpayment).FirstOrDefault();
how to use
var amountPaid = lastPayment.amountPaid; //1000
var invoiceNumber = lastPayment.invoiceNumber; //17289583

Deserialize Inconsistent JSON

I'm trying to create a basic Xamarin Forms app that can list available gateways on my PFsense firewall, Show the available gateway and change this to another gateway to route through if required. The problem I have is I cannot deserialize the JSON in C# because each object has a different object name:
{
"status": "ok",
"code": 200,
"return": 0,
"message": "Success",
"data": {
"GW_WAN_1": {
"interface": "hn0",
"gateway": "192.168.0.1",
"name": "GW_WAN_1",
"weight": "1",
"ipprotocol": "inet",
"interval": "500",
"time_period": "60000",
"alert_interval": "1000",
"descr": "Interface wan Gateway",
"data_payload": "1",
"latencylow": "200",
"latencyhigh": "500",
"losslow": "10",
"losshigh": "20",
"loss_interval": "2000",
"monitor": "192.168.0.1",
"friendlyiface": "wan",
"friendlyifdescr": "RED",
"isdefaultgw": true,
"attribute": 0,
"tiername": "Default (IPv4)"
},
"INT1_DHCP6": {
"dynamic": true,
"ipprotocol": "inet6",
"gateway": "fe80::1af1:45ff:fe90:4b13",
"interface": "hn0",
"friendlyiface": "wan",
"friendlyifdescr": "RED",
"name": "INT1_DHCP6",
"attribute": "system",
"isdefaultgw": true,
"monitor": "fe80::1af1:45ff:fe90:4b13",
"descr": "Interface RED_DHCP6 Gateway",
"tiername": ""
},
"VPN_EUR_1": {
"interface": "ovpns1",
"gateway": "192.168.1.2",
"name": "VPN_EUR_1",
"weight": "1",
"ipprotocol": "inet",
"interval": "500",
"time_period": "60000",
"alert_interval": "1000",
"descr": "Interface VPN_EUR_1 Gateway",
"data_payload": "1",
"latencylow": "200",
"latencyhigh": "500",
"losslow": "10",
"losshigh": "20",
"loss_interval": "2000",
"dynamic": true,
"monitor": "192.168.1.2",
"friendlyiface": "opt4",
"friendlyifdescr": "VPN_EUR_1",
"attribute": 1,
"tiername": ""
},
"Null4": {
"name": "Null4",
"interface": "lo0",
"ipprotocol": "inet",
"gateway": "127.0.0.1",
"attribute": "system",
"tiername": ""
},
"Null6": {
"name": "Null6",
"interface": "lo0",
"ipprotocol": "inet6",
"gateway": "::1",
"attribute": "system",
"tiername": ""
},
"VPN_EUR_1V6": {
"dynamic": false,
"ipprotocol": "inet6",
"gateway": null,
"interface": "ovpns1",
"friendlyiface": "opt4",
"friendlyifdescr": "VPN_EUR_1",
"name": "VPN_EUR_1V6",
"attribute": "system",
"descr": "Interface VPN_EUR_1V6 Gateway",
"tiername": ""
}
}
}
Here's how I've gone about trying to deserialize:
string authHeader = Constants.AUTH_HEADER;
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", authHeader);
var response = await client.GetAsync(Constants.GATEWAY);
var json = await response.Content.ReadAsStringAsync();
var gateways = JsonConvert.DeserializeObject<Data>(json);
The C# Object (Generated using json to C# converter):
public class GW_WAN_1
{
public string #interface { get; set; }
public string gateway { get; set; }
public string name { get; set; }
public string weight { get; set; }
public string ipprotocol { get; set; }
public string interval { get; set; }
public string time_period { get; set; }
public string alert_interval { get; set; }
public string descr { get; set; }
public string data_payload { get; set; }
public string latencylow { get; set; }
public string latencyhigh { get; set; }
public string losslow { get; set; }
public string losshigh { get; set; }
public string loss_interval { get; set; }
public string monitor { get; set; }
public string friendlyiface { get; set; }
public string friendlyifdescr { get; set; }
public bool isdefaultgw { get; set; }
public int attribute { get; set; }
public string tiername { get; set; }
}
public class INT1_DHCP6
{
public bool dynamic { get; set; }
public string ipprotocol { get; set; }
public string gateway { get; set; }
public string #interface { get; set; }
public string friendlyiface { get; set; }
public string friendlyifdescr { get; set; }
public string name { get; set; }
public string attribute { get; set; }
public bool isdefaultgw { get; set; }
public string monitor { get; set; }
public string descr { get; set; }
public string tiername { get; set; }
}
public class VPN_EUR_1
{
public string #interface { get; set; }
public string gateway { get; set; }
public string name { get; set; }
public string weight { get; set; }
public string ipprotocol { get; set; }
public string interval { get; set; }
public string time_period { get; set; }
public string alert_interval { get; set; }
public string descr { get; set; }
public string data_payload { get; set; }
public string latencylow { get; set; }
public string latencyhigh { get; set; }
public string losslow { get; set; }
public string losshigh { get; set; }
public string loss_interval { get; set; }
public bool dynamic { get; set; }
public string monitor { get; set; }
public string friendlyiface { get; set; }
public string friendlyifdescr { get; set; }
public int attribute { get; set; }
public string tiername { get; set; }
}
public class Null4
{
public string name { get; set; }
public string #interface { get; set; }
public string ipprotocol { get; set; }
public string gateway { get; set; }
public string attribute { get; set; }
public string tiername { get; set; }
}
public class Null6
{
public string name { get; set; }
public string #interface { get; set; }
public string ipprotocol { get; set; }
public string gateway { get; set; }
public string attribute { get; set; }
public string tiername { get; set; }
}
public class VPN_EUR_1V6
{
public bool dynamic { get; set; }
public string ipprotocol { get; set; }
public object gateway { get; set; }
public string #interface { get; set; }
public string friendlyiface { get; set; }
public string friendlyifdescr { get; set; }
public string name { get; set; }
public string attribute { get; set; }
public string descr { get; set; }
public string tiername { get; set; }
}
public class Data
{
public GW_WAN_1 GW_WAN { get; set; }
public INT1_DHCP6 INT1_DHCP6 { get; set; }
public VPN_EUR_1 VPN_EUR_1 { get; set; }
public Null4 Null4 { get; set; }
public Null6 Null6 { get; set; }
public VPN_EUR_1V6 VPN_NL_VPNV6 { get; set; }
}
public class Root
{
public string status { get; set; }
public int code { get; set; }
public int #return { get; set; }
public string message { get; set; }
public Data data { get; set; }
}
The problem is in the gateways variable, all of the properties are null. I think because of how the JSON is structured in the response, it might not be possible in C#, but perhaps there's another way of going about it?
The API for the firewall is here:
https://github.com/jaredhendrickson13/pfsense-api
Thanks

Deserialize JSON to List

I have this Json:
{
"trades": [
{
"id": "4004",
"instrument": "EUR_USD",
"price": "1.08938",
"openTime": "2020-02-26T12:15:32.309973340Z",
"initialUnits": "1",
"initialMarginRequired": "0.0363",
"state": "OPEN",
"currentUnits": "1",
"realizedPL": "0.0000",
"financing": "0.0000",
"dividendAdjustment": "0.0000",
"unrealizedPL": "-0.0026",
"marginUsed": "0.0362",
"takeProfitOrder": {
"id": "4005",
"createTime": "2020-02-26T12:15:32.309973340Z",
"type": "TAKE_PROFIT",
"tradeID": "4004",
"price": "1.09099",
"timeInForce": "GTC",
"triggerCondition": "DEFAULT",
"state": "PENDING"
}
}
],
"lastTransactionID": "4010"
}
And Classes:
public class TakeProfitOrder
{
public string id { get; set; }
public string createTime { get; set; }
public string type { get; set; }
public string tradeID { get; set; }
public string price { get; set; }
public string timeInForce { get; set; }
public string triggerCondition { get; set; }
public string state { get; set; }
}
public class Trade
{
public string id { get; set; }
public string instrument { get; set; }
public string price { get; set; }
public string openTime { get; set; }
public string initialUnits { get; set; }
public string initialMarginRequired { get; set; }
public string state { get; set; }
public string currentUnits { get; set; }
public string realizedPL { get; set; }
public string financing { get; set; }
public string dividendAdjustment { get; set; }
public string unrealizedPL { get; set; }
public string marginUsed { get; set; }
public TakeProfitOrder takeProfitOrder { get; set; }
}
public class RootObject
{
public List<Trade> trades { get; set; }
public string lastTransactionID { get; set; }
}
I deserialize with :
var result = JsonConvert.DeserializeObject<RootObject>(Json);
var price = result.trades.Select(p => p.price).ToList();
price.ForEach(Console.WriteLine);
It works. I can access "price" in "trades", but I do not know how to access the "price" in "takeProfitOrder". I need the value of "price" from "takeProfitOrder" in to a list. I am sure it is something very simple but I cannot figure out how to do it, even after looking at some similar examples.
Can somebody please help me?
It's simple
result.trades.Select(p => p.takeProfitOrder.price)
You should understand better from this example
foreach (Trade trade in result.trades)
{
TakeProfitOrder takeProfitOrder = trade.takeProfitOrder;
Console.WriteLine(takeProfitOrder.price);
}

C# class that would represent JSON data

what would the C# class definition look like to represent this JSON data?
{
"accountId": "101",
"website": "www.example.com",
"alternateWebsites": [
{
"website": "site2.example.com"
}
],
"email": "contact#mysite.com",
"alternateEmails": [
{
"email": "sales#example.com"
}
],
"address": {
"street": "234 Main Street",
"city": "San Diego",
"postalCode": "92101",
"state": "CA"
},
"rankingKeywords":
[{
"keyword": "Coffee",
"localArea": "Sacramento, CA"
}]
}
You can use a site like this http://jsonutils.com/
where you paste in your json and it constructs your classes for you. The result of your JSON produced...
public class AlternateWebsite
{
public string website { get; set; }
}
public class AlternateEmail
{
public string email { get; set; }
}
public class Address
{
public string street { get; set; }
public string city { get; set; }
public string postalCode { get; set; }
public string state { get; set; }
}
public class RankingKeyword
{
public string keyword { get; set; }
public string localArea { get; set; }
}
public class Root
{
public string accountId { get; set; }
public string website { get; set; }
public IList<AlternateWebsite> alternateWebsites { get; set; }
public string email { get; set; }
public IList<AlternateEmail> alternateEmails { get; set; }
public Address address { get; set; }
public IList<RankingKeyword> rankingKeywords { get; set; }
}
You could convert this with a service like http://json2csharp.com/. Enter the JSON and it will spit out C# model classes. Then, add them either as a class, or using Entity Framework (depending on your objective) into your project.
C# version:
public class AlternateWebsite
{
public string website { get; set; }
}
public class AlternateEmail
{
public string email { get; set; }
}
public class Address
{
public string street { get; set; }
public string city { get; set; }
public string postalCode { get; set; }
public string state { get; set; }
}
public class RankingKeyword
{
public string keyword { get; set; }
public string localArea { get; set; }
}
public class RootObject
{
public string accountId { get; set; }
public string website { get; set; }
public List<AlternateWebsite> alternateWebsites { get; set; }
public string email { get; set; }
public List<AlternateEmail> alternateEmails { get; set; }
public Address address { get; set; }
public List<RankingKeyword> rankingKeywords { get; set; }
}

How to Deserialize deeply nested json array in asp.net C#

JSon String is given below:
{
"properties": {
"jci": [
{
"firstName": "Henk",
"lastName": "de Vries",
"Photo": "http://s3.amazonaws.com/mendeley-photos/6a/bd/6abdab776feb7a1fd4e5b4979ea9c5bfc754fd29.png",
"Title": "Dr.",
"Position": "Head of research group",
"Institution": "Vrije Universiteit Amsterdam",
"Fields_of_interest": ["medicine", "computer science"],
"emailAddress": "henk.de.vries#science.com",
"editorship": [
{
"title": "Dr.",
"editorial_role": "Editor in chief",
"date_start": 1460116283,
"date_end": 1460116283,
"publisher": {
"name": "Elsevier",
"role": "Project manager",
"emailAddress": "journal#elsevier.com"
}
}
]
}
],
"sid": [
{
"firstName": "Henk",
"lastName": "de Vries",
"Title": "Dr.",
"primary organisation": "Vrije Universiteit Amsterdam",
"emailAddress": "henk.de.vries#science.com",
"editorship": [
{
"title": "Dr.",
"editorial_role": "Editor in chief",
"publication_year": 2012
}
]
}
]
}
}
I have written code to deserialization
JavaScriptSerializer ser = new JavaScriptSerializer();
JsonTest foo = new JsonTest();
foo = (JsonTest)ser.Deserialize<JsonTest>(JSONString);
public class JsonTest
{
public properties properties { get; set; }
}
public class properties
{
public List<jci> jci { get; set; }
public List<sid>sid { get; set; }
}
public class jci
{
public string firstName { get; set; }
public string lastName { get; set; }
public string Photo { get; set; }
public string Position { get; set; }
public string Institution { get; set; }
public string emailAddress { get; set; }
public string Title { get; set; }
public List<string> Fields_of_interest { get; set; }
public List<editorship> editorship { get; set; }
}
public class editorship
{
public string title { get; set; }
public string editorial_role { get; set; }
public string date_start { get; set; }
public string date_end { get; set; }
public Dictionary<string, string> publisher { get; set; }
}
in this code there are 2 arrays of object called "editorship".. I have created "editorship" class for "jci".. how to access the values of editorship array of sid...?
Using json2csharp i generated these classes based on your JSON
public class Publisher
{
public string name { get; set; }
public string role { get; set; }
public string emailAddress { get; set; }
}
public class Editorship
{
public string title { get; set; }
public string editorial_role { get; set; }
public int date_start { get; set; }
public int date_end { get; set; }
public Publisher publisher { get; set; }
}
public class Jci
{
public string firstName { get; set; }
public string lastName { get; set; }
public string Photo { get; set; }
public string Title { get; set; }
public string Position { get; set; }
public string Institution { get; set; }
public List<string> Fields_of_interest { get; set; }
public string emailAddress { get; set; }
public List<Editorship> editorship { get; set; }
}
public class Editorship2
{
public string title { get; set; }
public string editorial_role { get; set; }
public int publication_year { get; set; }
}
public class Sid
{
public string firstName { get; set; }
public string lastName { get; set; }
public string Title { get; set; }
public string primary_organisation { get; set; }
public string emailAddress { get; set; }
public List<Editorship2> editorship { get; set; }
}
public class Properties
{
public List<Jci> jci { get; set; }
public List<Sid> sid { get; set; }
}
public class RootObject
{
public Properties properties { get; set; }
}
You can then access your editorial values like this:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var collection = serializer.Deserialize<RootObject>(jsonString);
foreach (var j in collection.properties.sid)
{
Console.Write(j.editorship);
}
On a side note, you should consider using names that are more readable then jci and sid

Categories