hello i have a few classes and i have problem looping through some of the classes to get the values.
eg, i want to know which sensors are having issues. sensors comprises of lidar, imu, camera1234. i want so check their status and if their status is not 'good' then i need to say 'lidar not good'.
ways that i have thought of:
list of classes? but what is the 'Type' for classes?
using Root class, access the other classes from it, similar to how we do for iterating through properties in classes. but how do i do this?
public class Battery
{
public string status { get; set; }
public string value { get; set; }
}
public class Camera1
{
public string status { get; set; }
}
public class Camera2
{
public string status { get; set; }
}
public class Camera3
{
public string status { get; set; }
}
public class Camera4
{
public string status { get; set; }
}
public class Cpu
{
public string status { get; set; }
public string value { get; set; }
public string temperature { get; set; }
public string ram { get; set; }
public string utilisation { get; set; }
}
public class CurrentJob
{
public object job { get; set; }
public object task { get; set; }
public object location { get; set; }
}
public class Dex
{
public CurrentJob current_job { get; set; }
public Battery battery { get; set; }
public Gpu gpu { get; set; }
public Cpu cpu { get; set; }
public Lidar lidar { get; set; }
public Camera1 camera1 { get; set; }
public Camera2 camera2 { get; set; }
public Camera3 camera3 { get; set; }
public Camera4 camera4 { get; set; }
public Imu imu { get; set; }
}
public class Gpu
{
public string status { get; set; }
public string value { get; set; }
public string memory { get; set; }
public string utilisation { get; set; }
}
public class Imu
{
public string status { get; set; }
}
public class Lidar
{
public string status { get; set; }
}
public class Root
{
public Dex dex { get; set; }
}
this is my json
[
{"dex":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"status": "good", "value": "100"},
"gpu":
{"status": "bad", "value": "97", "memory":"60", "utilisation":"83.3"},
"cpu":
{"status": "good", "value": "32", "temperature":"37", "ram":"31.5", "utilisation":"26"},
"lidar":
{"status": "good"},
"camera1":
{"status": "good"},
"camera2":
{"status": "good"},
"camera3":
{"status": "error"},
"camera4":
{"status": "good"},
"imu":
{"status": "good"}
}
}
]
after implementing advice from JEremey, this is my updated classes
using System.Text;
using Microsoft.Bot.Builder;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.IO;
namespace CoreBot.CognitiveModels
{
public class Battery
{
public string status { get; set; }
public string value { get; set; }
}
public class Camera1 : SensorComponents
{
public string status { get; set; }
}
public class Camera2 : SensorComponents
{
public string status { get; set; }
}
public class Camera3 : SensorComponents
{
public string name = "CPU";
public string status { get; set; }
}
public class Camera4 : SensorComponents
{
public string status { get; set; }
}
public class Cpu
{
public string name = "CPU";
public string status { get; set; }
public string value { get; set; }
public string temperature { get; set; }
public string ram { get; set; }
public string utilisation { get; set; }
}
public class CurrentJob
{
public object job { get; set; }
public object task { get; set; }
public object location { get; set; }
}
public class Dex
{
public CurrentJob current_job { get; set; }
public Battery battery { get; set; }
public Gpu gpu { get; set; }
public Cpu cpu { get; set; }
public Lidar lidar { get; set; }
public Camera1 camera1 { get; set; }
public Camera2 camera2 { get; set; }
public Camera3 camera3 { get; set; }
public Camera4 camera4 { get; set; }
public Imu imu { get; set; }
}
public class Gpu
{
public string status { get; set; }
public string value { get; set; }
public string memory { get; set; }
public string utilisation { get; set; }
}
public class Imu : SensorComponents
{
public string status { get; set; }
}
public class Lidar : SensorComponents
{
public string status { get; set; }
}
public class Root
{
public Dex dex { get; set; }
}
public class SensorComponents
{
public string name { get; set;}
public string status { get; set;}
}
}
I'll throw you a bone. The classes all share a Status Property so create a base class called
class Device{
public string name { get; set; }
public string status { get; set; }
}
Now all your classes can derive from it:
public class Camera1 : Device
{ ]
Then you can have a List<Device> devices = new(); and iterate over that
foreach(var device in devices)
{
if (device.status == "good")
{
System.Diagnostics.Debug.WriteLine(device.Name + " all good");
}
else
{
System.Diagnostics.Debug.WriteLine(device.Name + " not good");
}
}
It can depend in some scenarios it maybe better to use an Interface:
public interface IDevice{
string GetName();
string GetStatus();
}
Implement these in your classes:
public class Camera1 : IDevice
{
public string GetStatus(){
return "good";
}
}
Then you could iterate over anything that implements the Interface (not tested):
List<IDevice> idevices = new List<IDevice>();
idevices.Add(new Camera1());
idevices.Add(new Camera2());
idevices.Add(new Camera3());
foreach(var device in idevices)
{
System.Diagnostics.Debug.WriteLine(device.GetStatus());
}
Saw that JEremey proposed something good while I was writing, but here is "another bone", in a similar fashion.
Note:
I was more minimal in my interface design (I took care only of the Status part, not even the name).
As per the description of your description, I think something much more detailed is needed for status, even a class for itself. Status seems a complex thing where you want to read / store various information (like a boolean value to tell if is it good or not + a description or what is the issue if any). But below I kepty status as a simple string for a start.
using System;
using System.Linq;
using System.Collections.Generic;
public interface HasStatus
{
string Status { get; set; }
}
public class Battery : HasStatus
{
public string Status { get; set; }
public string Value { get; set; }
}
public class Camera : HasStatus
{
public string Status { get; set; }
public int Id { get; set; }
}
public class Cpu : HasStatus
{
public string Status { get; set; }
public string Value { get; set; }
public string Temperature { get; set; }
public string Ram { get; set; }
public string Utilisation { get; set; }
}
class HelloWorld {
static void Main() {
Console.WriteLine("Hello World");
var allMyStuff = new List<HasStatus>
{
new Camera { Id = 111, Status = "Good" },
new Camera { Id = 200, Status = "Sensor has a problem" },
new Camera { Id = 304, Status = "Good" },
new Camera { Id = 467, Status = "Good" },
new Cpu { Status = "Doesn't run very fast", Ram = "1MB" },
new Battery { Value = "a lot", Status = "Good" }
};
int i = 0;
foreach (var stuff in allMyStuff)
{
Console.WriteLine($"Status of object N° {i} of type {stuff.GetType().Name} is '{stuff.Status}'");
i++;
}
}
}
You can filter the not-good ones, for instance with :
var allNotGoodStuff = allMyStuff.Where(x => x.Status != "Good");
foreach (var badStuff in allNotGoodStuff)
{
// Do some display or anything else with each bad stuff here...
}
Related
I am receiving json with dynamic one node based on sector like "DEL-BOM", "NYC-BOM".
trying to parse but body getting null.
I just add Dictionary and key as node and class as value but still not getting values in DeserializeObject.
{
"fareRule": {
"DEL-BOM": {
"fr": {
"NO_SHOW": {
"DEFAULT": {
"policyInfo": "If Cancelled within 6 hrs of scheduled departure only statutory taxes will be Refunded."
}
},
"DATECHANGE": {
"DEFAULT": {
"amount": 3000.00,
"additionalFee": 50.00,
"policyInfo": "__nls__Changes permitted 06 Hrs before scheduled departure __nls__ Within 06-96 hrs Rs 3,000 + Fare Difference __nls__ Before 96 hrs Rs 2,500 + Fare Difference",
"fcs": {
"CRFT": 9.00,
"ARF": 3000.00,
"ARFT": 150.00,
"CRF": 50.00
}
}
},
"CANCELLATION": {
"DEFAULT": {
"amount": 3500.00,
"additionalFee": 50.00,
"policyInfo": "__nls__Cancellation permitted 06 Hrs before scheduled departure __nls__ Within 06-96 hrs Rs 3,500 __nls__ Before 96 hrs Rs 3,000",
"fcs": {
"ACFT": 175.00,
"CCFT": 9.00,
"ACF": 3500.00,
"CCF": 50.00
}
}
},
"SEAT_CHARGEABLE": {
"DEFAULT": {
"policyInfo": "Paid Seat"
}
}
}
}
},
"status": {
"success": true,
"httpStatus": 200
}
}
this is my class
public class Response
{
public Dictionary<string, Fr> fareRule { get; set; }
public Status status { get; set; }
}
public class DEFAULT
{
public string policyInfo { get; set; }
public double amount { get; set; }
public double additionalFee { get; set; }
public Fcs fcs { get; set; }
}
public class NOSHOW
{
public DEFAULT DEFAULT { get; set; }
}
public class Fcs
{
public double ARFT { get; set; }
public double ARF { get; set; }
public double CRFT { get; set; }
public double CRF { get; set; }
public double CCF { get; set; }
public double ACF { get; set; }
public double CCFT { get; set; }
public double ACFT { get; set; }
}
public class DATECHANGE
{
public DEFAULT DEFAULT { get; set; }
}
public class CANCELLATION
{
public DEFAULT DEFAULT { get; set; }
}
public class SEATCHARGEABLE
{
public DEFAULT DEFAULT { get; set; }
}
public class Fr
{
public NOSHOW NO_SHOW { get; set; }
public DATECHANGE DATECHANGE { get; set; }
public CANCELLATION CANCELLATION { get; set; }
public SEATCHARGEABLE SEAT_CHARGEABLE { get; set; }
}
public class Sector
{
public Fr fr { get; set; }
}
public class FareRule
{
public Sector sector { get; set; }
}
public class Status
{
public bool success { get; set; }
public int httpStatus { get; set; }
}
I have tried based on Parse dynamic JSON
Key is converting but body or value is null.
try this, it was tested and working properly
var jsonDeserialized = JsonConvert.DeserializeObject<Data>(json);
classes
public class Data
{
public Dictionary<string,Dictionary<string, Mode>> fareRule { get; set; }
public Status status { get; set; }
}
public class Status
{
public bool? success { get; set; }
public int? httpStatus { get; set; }
}
public class DEFAULT
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string policyInfo { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public double? amount { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public double? additionalFee { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string,double?> fcs { get; set; }
}
public class NOSHOW
{
public DEFAULT DEFAULT { get; set; }
}
public class DATECHANGE
{
public DEFAULT DEFAULT { get; set; }
}
public class CANCELLATION
{
public DEFAULT DEFAULT { get; set; }
}
public class SEATCHARGEABLE
{
public DEFAULT DEFAULT { get; set; }
}
public class Mode
{
public NOSHOW NO_SHOW { get; set; }
public DATECHANGE DATECHANGE { get; set; }
public CANCELLATION CANCELLATION { get; set; }
public SEATCHARGEABLE SEAT_CHARGEABLE { get; set; }
}
Use Newtonsoft.Json for deserialization
Your Correct Model is.
public class DATECHANGE
{
public DEFAULT DEFAULT { get; set; }
}
public class CANCELLATION
{
public DEFAULT DEFAULT { get; set; }
}
public class SEATCHARGEABLE
{
public DEFAULT DEFAULT { get; set; }
}
public class Fr
{
public NOSHOW NO_SHOW { get; set; }
public DATECHANGE DATECHANGE { get; set; }
public CANCELLATION CANCELLATION { get; set; }
public SEATCHARGEABLE SEAT_CHARGEABLE { get; set; }
}
public class FareRule
{
[JsonProperty(PropertyName = "DEL-BOM")]
public DynamicBody DELBOM { get; set; }
[JsonProperty(PropertyName = "NYC-BOM")]
public DynamicBody NYCBOM { get; set; }
}
public class Status
{
public bool Success { get; set; }
public int HttpStatus { get; set; }
}
public class BaseResponseModel
{
public FareRule FareRule { get; set; }
public Status Status { get; set; }
}
public class DynamicBody
{
public Fr Fr { get; set; }
}
Then Deserialize like this code
var responseModel = JsonConvert.DeserializeObject<BaseResponseModel>(jsonStr);
I have a nested json string, instead of using arrays the next level is another json structure. This creates a mess of deserializing using traditional methods.
Most other answers dealing with parsing json have clearly defined structures, and in most cases can be solved using online tools such as http://json2csharp.com/. But because this JSON doesn't use arrays properly I'm having trouble coming up with a solution to deserialize it.
For example:
{
"time":1516824466,
"global":{
"workers":1,
"hashrate":0
},
"algos":{
"scrypt-n":{
"workers":1,
"hashrate":79752.92436043094,
"hashrateString":"79.75 KH"
}
},
"pools":{
"garlicoin":{
"name":"garlicoin",
"symbol":"GRLC",
"algorithm":"scrypt-n",
"poolStats":{
"validShares":"22855",
"validBlocks":"3",
"invalidShares":"59",
"invalidRate":"0.0026",
"totalPaid":"296.42722209999999999"
},
"blocks":{
"pending":0,
"confirmed":2,
"orphaned":1
},
"workers":{
"Gf3ZXqhWKkm8qLhSHvyrawiCiooYeU9eQu":{
"shares":365.07991498000007,
"invalidshares":0,
"hashrate":79752.92436043094,
"hashrateString":"79.75 KH"
},
"Gz2Llan6hTkm8qLhSHh34awiCiooYe17heT":{
"shares":365.07991498000007,
"invalidshares":0,
"hashrate":79752.92436043094,
"hashrateString":"79.75 KH"
}
},
"hashrate":79752.92436043094,
"workerCount":1,
"hashrateString":"79.75 KH"
}
}
}
I'm having trouble deserializing these two parts specifically:
"algos":{
"scrypt-n":{
"workers":1,
"hashrate":79752.92436043094,
"hashrateString":"79.75 KH"
}
},
"workers":{
"Gf3ZXqhWKkm8qLhSHvyrawiCiooYeU9eQu":{
"shares":365.07991498000007,
"invalidshares":0,
"hashrate":79752.92436043094,
"hashrateString":"79.75 KH"
},
"Gz2Llan6hTkm8qLhSHh34awiCiooYe17heT":{
"shares":365.07991498000007,
"invalidshares":0,
"hashrate":79752.92436043094,
"hashrateString":"79.75 KH"
}
},
The Code I've Tried
namespace pooldecode
{
public static class Serialize
{
public static string ToJson(this jsonDecode.Root self)
{
return JsonConvert.SerializeObject(self, Converter.Settings);
}
}
public class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
};
}
public class jsonDecode
{
public static Root FromJson(string json) => JsonConvert.DeserializeObject<Root>(json/*, Converter.Settings*/);
public partial class Root
{
[J("time")] public long Time { get; set; }
[J("global")] public Global Global { get; set; }
[J("algos")] public List<Algos> Algos { get; set; }
[J("pools")] public List<Pools> Pools { get; set; }
}
public partial class Algos
{
[J("workers")] public int Workers { get; set; }
[J("hashrate")] public double Hashrate { get; set; }
[J("hashrateString")] public string HashrateString { get; set; }
}
public partial class Global
{
[J("workers")] public int Workers { get; set; }
[J("hashrate")] public long Hashrate { get; set; }
}
public partial class Pools
{
[J("crypto")] public List<Crypto> Crypto { get; set; }
}
public partial class Crypto
{
[J("name")] public string Name { get; set; }
[J("symbol")] public string Symbol { get; set; }
[J("algorithm")] public string Algorithm { get; set; }
[J("poolStats")] public PoolStats PoolStats { get; set; }
[J("blocks")] public Blocks Blocks { get; set; }
[J("workers")] public Workers Workers { get; set; }
[J("hashrate")] public double Hashrate { get; set; }
[J("workerCount")] public long WorkerCount { get; set; }
[J("hashrateString")] public string HashrateString { get; set; }
}
public partial class Blocks
{
[J("pending")] public long Pending { get; set; }
[J("confirmed")] public long Confirmed { get; set; }
[J("orphaned")] public long Orphaned { get; set; }
}
public partial class PoolStats
{
[J("validShares")] public string ValidShares { get; set; }
[J("validBlocks")] public string ValidBlocks { get; set; }
[J("invalidShares")] public string InvalidShares { get; set; }
[J("invalidRate")] public string InvalidRate { get; set; }
[J("totalPaid")] public string TotalPaid { get; set; }
}
public partial class Workers
{
[J("worker")] public List<Workers> Worker { get; set; }
[J("shares")] public double Shares { get; set; }
[J("invalidshares")] public long Invalidshares { get; set; }
[J("hashrate")] public double Hashrate { get; set; }
[J("hashrateString")] public string HashrateString { get; set; }
}
public partial class Worker
{
[J("shares")] public double Shares { get; set; }
[J("invalidshares")] public long Invalidshares { get; set; }
[J("hashrate")] public double Hashrate { get; set; }
[J("hashrateString")] public string HashrateString { get; set; }
}
}
}
Algos, Pools and Workers have named properties as childrens, you can't deserialize them as List<T> since they are Dictionary<string, T>,
Use these classes to deserialize:
public partial class Root
{
[JsonPropertyAttribute("time")] public long Time { get; set; }
[JsonPropertyAttribute("global")] public Global Global { get; set; }
[JsonPropertyAttribute("algos")] public Dictionary<string, Algo> Algos { get; set; }
[JsonPropertyAttribute("pools")] public Dictionary<string, Pool> Pools { get; set; }
}
public partial class Global
{
[JsonPropertyAttribute("workers")] public int Workers { get; set; }
[JsonPropertyAttribute("hashrate")] public long Hashrate { get; set; }
}
public partial class Algo
{
[JsonPropertyAttribute("workers")] public int Workers { get; set; }
[JsonPropertyAttribute("hashrate")] public double Hashrate { get; set; }
[JsonPropertyAttribute("hashrateString")] public string HashrateString { get; set; }
}
public partial class Pool
{
[JsonPropertyAttribute("name")] public string Name { get; set; }
[JsonPropertyAttribute("symbol")] public string Symbol { get; set; }
[JsonPropertyAttribute("algorithm")] public string Algorithm { get; set; }
[JsonPropertyAttribute("poolStats")] public PoolStats PoolStats { get; set; }
[JsonPropertyAttribute("blocks")] public Blocks Blocks { get; set; }
[JsonPropertyAttribute("workers")] public Dictionary<string, Worker> Workers { get; set; }
[JsonPropertyAttribute("hashrate")] public double Hashrate { get; set; }
[JsonPropertyAttribute("workerCount")] public long WorkerCount { get; set; }
[JsonPropertyAttribute("hashrateString")] public string HashrateString { get; set; }
}
public partial class Blocks
{
[JsonPropertyAttribute("pending")] public long Pending { get; set; }
[JsonPropertyAttribute("confirmed")] public long Confirmed { get; set; }
[JsonPropertyAttribute("orphaned")] public long Orphaned { get; set; }
}
public partial class PoolStats
{
[JsonPropertyAttribute("validShares")] public string ValidShares { get; set; }
[JsonPropertyAttribute("validBlocks")] public string ValidBlocks { get; set; }
[JsonPropertyAttribute("invalidShares")] public string InvalidShares { get; set; }
[JsonPropertyAttribute("invalidRate")] public string InvalidRate { get; set; }
[JsonPropertyAttribute("totalPaid")] public string TotalPaid { get; set; }
}
public partial class Worker
{
[JsonPropertyAttribute("shares")] public double Shares { get; set; }
[JsonPropertyAttribute("invalidshares")] public long Invalidshares { get; set; }
[JsonPropertyAttribute("hashrate")] public double Hashrate { get; set; }
[JsonPropertyAttribute("hashrateString")] public string HashrateString { get; set; }
}
{
"StudentInformation": {
"rollNumber": null,
"isClassLeader": false,
"result": "Pass"
},
"CollegeInformation": {
"allClass": ["A", "B"],
"currencyAccepted": "INR",
"calendarDates": [],
"currencyCode": "INR",
"collegeCode": null,
"hasBulidingFundPrices": false,
"hasHostel": false,
"hasSecurityFares": false
},
"Collegetrips": [{
"tripsdate": [{
"departureTripDate": "2017-08-15 00:00:00",
"Places": [{
"destination": "Bombay",
"price": [{
"priceAmount": 1726
}]
}]
}]
}]
}
In the above json file i need to retrieve only "priceAmount": 1726. Please anyone suggest how can able to achieve?
You can use System.Web.Script.Serialization (you need to add a reference to System.Web.Extensions):
dynamic json = new JavaScriptSerializer()
.DeserializeObject(jsonString);
decimal price = json["Collegetrips"][0]
["tripsdate"][0]
["Places"][0]
["price"][0]
["priceAmount"]; // 1726
Note that you can pretty much traverse the json in this manner using indexes and key names.
Hi try this,
public void Main()
{
string sJSON = "{\"StudentInformation\": {\"rollNumber\": null,\"isClassLeader\": false,\"result\": \"Pass\"},\"CollegeInformation\": {\"allClass\": [\"A\", \"B\"],\"currencyAccepted\": \"INR\",\"calendarDates\": [],\"currencyCode\": \"INR\",\"collegeCode\": null,\"hasBulidingFundPrices\": false,\"hasHostel\": false,\"hasSecurityFares\": false},\"Collegetrips\": [{\"tripsdate\": [{\"departureTripDate\": \"2017-08-15 00:00:00\",\"Places\": [{\"destination\": \"Bombay\",\"price\": [{\"priceAmount\": 1726}]}]}]}]}";
Rootobject obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(sJSON);
Price price = obj.Collegetrips.Select(ct =>
{
var r = ct.tripsdate.Select(td =>
{
var r1 = td.Places.Select(p =>
{
Price itemPrice = p.price.FirstOrDefault();
return itemPrice;
}).FirstOrDefault();
return r1;
}).FirstOrDefault();
return r;
}).FirstOrDefault();
if (price != null)
Console.Write(price.priceAmount);
else
Console.Write("Not Found!");
}
public class Rootobject
{
public Studentinformation StudentInformation { get; set; }
public Collegeinformation CollegeInformation { get; set; }
public Collegetrip[] Collegetrips { get; set; }
}
public class Studentinformation
{
public object rollNumber { get; set; }
public bool isClassLeader { get; set; }
public string result { get; set; }
}
public class Collegeinformation
{
public string[] allClass { get; set; }
public string currencyAccepted { get; set; }
public object[] calendarDates { get; set; }
public string currencyCode { get; set; }
public object collegeCode { get; set; }
public bool hasBulidingFundPrices { get; set; }
public bool hasHostel { get; set; }
public bool hasSecurityFares { get; set; }
}
public class Collegetrip
{
public Tripsdate[] tripsdate { get; set; }
}
public class Tripsdate
{
public string departureTripDate { get; set; }
public Place[] Places { get; set; }
}
public class Place
{
public string destination { get; set; }
public Price[] price { get; set; }
}
public class Price
{
public int priceAmount { get; set; }
}
I use:
http://json2csharp.com/
to get a class representing the Json Object.
public class StudentInformation
{
public object rollNumber { get; set; }
public bool isClassLeader { get; set; }
public string result { get; set; }
}
public class CollegeInformation
{
public List<string> allClass { get; set; }
public string currencyAccepted { get; set; }
public List<object> calendarDates { get; set; }
public string currencyCode { get; set; }
public object collegeCode { get; set; }
public bool hasBulidingFundPrices { get; set; }
public bool hasHostel { get; set; }
public bool hasSecurityFares { get; set; }
}
public class Price
{
public int priceAmount { get; set; }
}
public class Place
{
public string destination { get; set; }
public List<Price> price { get; set; }
}
public class Tripsdate
{
public string departureTripDate { get; set; }
public List<Place> Places { get; set; }
}
public class Collegetrip
{
public List<Tripsdate> tripsdate { get; set; }
}
public class JsonResponse
{
public StudentInformation StudentInformation { get; set; }
public CollegeInformation CollegeInformation { get; set; }
public List<Collegetrip> Collegetrips { get; set; }
}
After that I use Newtonsoft.Json to fill the Class:
using Newtonsoft.Json;
namespace GitRepositoryCreator.Common
{
class JObjects
{
public static string Get(object p_object)
{
return JsonConvert.SerializeObject(p_object);
}
internal static T Get<T>(string p_object)
{
return JsonConvert.DeserializeObject<T>(p_object);
}
}
}
You can call it like that:
JsonResponse jsonClass = JObjects.Get<JsonResponse>(stringJson);
string stringJson = JObjects.Get(jsonClass);
PS:
If your json variable name is no valid C# name you can fix that like this:
public class Exception
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
public object innerException { get; set; }
public string message { get; set; }
public string typeName { get; set; }
public string typeKey { get; set; }
public int errorCode { get; set; }
public int eventId { get; set; }
}
I am working on an integration with the Expedia API. I am relatively new to ServiceStack but have managed pretty well so far, however, I've hit an issue with the deserialization of a JSON response from the API which seems to be failing despite having JsConfig.ThrowOnDeserializationError enabled.
JsConfig.Reset();
JsConfig.ThrowOnDeserializationError = true;
var availability = _client.Get<ExpediaHotelRoomAvailability>("avail?" + querystring);
In order to see the API response I am working with please use the following request:
GET http://dev.api.ean.com/ean-services/rs/hotel/v3/avail?minorRev=26&cid=55505&apiKey=cbrzfta369qwyrm9t5b8y8kf&customerUserAgent=Mozilla%2f5.0+(Windows+NT+6.3%3b+WOW64)+AppleWebKit%2f537.36+(KHTML%2c+like+Gecko)+Chrome%2f35.0.1916.114+Safari%2f537.36&customerIpAddress=%3a%3a1&hotelId=135857&arrivalDate=06%2f07%2f2014&departureDate=06%2f20%2f2014&includeDetails=true&includeRoomImages=true&room1=2 HTTP/1.1
User-Agent: Fiddler
Content-Type: text/json
Host: dev.api.ean.com
Here is a typical response:
{
"HotelRoomAvailabilityResponse":{
"#size":"1",
"customerSessionId":"0ABAAA7A-D42E-2914-64D2-01C0F09040D8",
"hotelId":135857,
"arrivalDate":"06\/07\/2014",
"departureDate":"06\/20\/2014",
"hotelName":"La Quinta Inn and Suites Raleigh Cary",
"hotelAddress":"191 Crescent Commons",
"hotelCity":"Cary",
"hotelStateProvince":"NC",
"hotelCountry":"US",
"numberOfRoomsRequested":1,
"checkInInstructions":"",
"tripAdvisorRating":4.5,
"tripAdvisorReviewCount":189,
"tripAdvisorRatingUrl":"http:\/\/www.tripadvisor.com\/img\/cdsi\/img2\/ratings\/traveler\/4.5-12345-4.gif",
"HotelRoomResponse":{
"rateCode":14587,
"roomTypeCode":14587,
"rateDescription":"Standard Room, 1 King Bed",
"roomTypeDescription":"Standard Room, 1 King Bed",
"supplierType":"E",
"propertyId":67977,
"BedTypes":{
"#size":"1",
"BedType":{
"#id":"14",
"description":"1 king"
}
},
"smokingPreferences":"S,NS",
"rateOccupancyPerRoom":3,
"quotedOccupancy":2,
"minGuestAge":0,
"RateInfos":{
"#size":"1",
"RateInfo":{
"#priceBreakdown":"true",
"#promo":"false",
"#rateChange":"true",
"RoomGroup":{
"Room":{
"numberOfAdults":2,
"numberOfChildren":0,
"rateKey":"0214364d-6819-4631-aa97-a162c43e0297"
}
},
"ChargeableRateInfo":{
"#averageBaseRate":"109.61539",
"#averageRate":"109.61539",
"#commissionableUsdTotal":"1425.0",
"#currencyCode":"USD",
"#maxNightlyRate":"165.0",
"#nightlyRateTotal":"1425.0",
"#surchargeTotal":"229.19",
"#total":"1654.19",
"NightlyRatesPerRoom":{
"#size":"13",
"NightlyRate":[
{
"#baseRate":"90.0",
"#rate":"90.0",
"#promo":"false"
},
{
"#baseRate":"90.0",
"#rate":"90.0",
"#promo":"false"
},
{
"#baseRate":"100.0",
"#rate":"100.0",
"#promo":"false"
},
{
"#baseRate":"115.0",
"#rate":"115.0",
"#promo":"false"
},
{
"#baseRate":"115.0",
"#rate":"115.0",
"#promo":"false"
},
{
"#baseRate":"115.0",
"#rate":"115.0",
"#promo":"false"
},
{
"#baseRate":"165.0",
"#rate":"165.0",
"#promo":"false"
},
{
"#baseRate":"165.0",
"#rate":"165.0",
"#promo":"false"
},
{
"#baseRate":"90.0",
"#rate":"90.0",
"#promo":"false"
},
{
"#baseRate":"95.0",
"#rate":"95.0",
"#promo":"false"
},
{
"#baseRate":"95.0",
"#rate":"95.0",
"#promo":"false"
},
{
"#baseRate":"95.0",
"#rate":"95.0",
"#promo":"false"
},
{
"#baseRate":"95.0",
"#rate":"95.0",
"#promo":"false"
}
]
},
"Surcharges":{
"#size":"1",
"Surcharge":{
"#type":"TaxAndServiceFee",
"#amount":"229.19"
}
}
},
"cancellationPolicy":"We understand that sometimes your travel plans change. We do not charge a change or cancel fee. However, this property (La Quinta Inn and Suites Raleigh Cary) imposes the following penalty to its customers that we are required to pass on: Cancellations or changes made after 6:00 PM ((GMT-05:00) Eastern Time (US & Canada)) on Jun 6, 2014 are subject to a 1 Night Room & Tax penalty. The property makes no refunds for no shows or early checkouts.",
"CancelPolicyInfoList":{
"CancelPolicyInfo":[
{
"versionId":208699803,
"cancelTime":"18:00:00",
"startWindowHours":0,
"nightCount":1,
"currencyCode":"USD",
"timeZoneDescription":"(GMT-05:00) Eastern Time (US & Canada)"
},
{
"versionId":208778550,
"cancelTime":"18:00:00",
"startWindowHours":24,
"nightCount":0,
"currencyCode":"USD",
"timeZoneDescription":"(GMT-05:00) Eastern Time (US & Canada)"
}
]
},
"nonRefundable":false,
"rateType":"MerchantStandard",
"currentAllotment":0,
"guaranteeRequired":false,
"depositRequired":true,
"taxRate":229.19
}
},
"ValueAdds":{
"#size":"3",
"ValueAdd":[
{
"#id":"2048",
"description":"Free Wireless Internet"
},
{
"#id":"2",
"description":"Continental Breakfast"
},
{
"#id":"128",
"description":"Free Parking"
}
]
},
"deepLink":"https:\/\/travel.ian.com\/templates\/55505\/hotels\/135857\/book?lang=en&standardCheckin=06\/07\/2014&standardCheckout=06\/20\/2014&selectedPrice=1654.190000&supplierType=E&rateCode=14587&roomTypeCode=14587&roomsCount=1&rooms[0].adultsCount=2&rateKey=0214364d-6819-4631-aa97-a162c43e0297",
"RoomImages":{
"#size":"1",
"RoomImage":{
"url":"http:\/\/media.expedia.com\/hotels\/1000000\/70000\/68000\/67977\/67977_103_s.jpg"
}
}
}
}
}
A large part of the response is de-serialized fine except for all of the rate information which I am really interested in. No exceptions are thrown during the deserialization so I have little to go on in terms of tracking down the exact problem. To be more specific let's take the ChargeableRateInfo - all values contained within are either null or zero.
Here is my class I am trying to deserialize the response to:
namespace MyCustomNamespace
{
using System.Collections.Generic;
public class BedType
{
public string description { get; set; }
public string id { get; set; }
}
public class BedTypes
{
public BedType BedType { get; set; }
public int size { get; set; }
}
public class Room
{
public int numberOfAdults { get; set; }
public int numberOfChildren { get; set; }
public string rateKey { get; set; }
}
public class RoomGroup
{
public Room Room { get; set; }
}
public class NightlyRate
{
public string baseRate { get; set; }
public string promo { get; set; }
public string rate { get; set; }
}
public class NightlyRatesPerRoom
{
public List<NightlyRate> NightlyRate { get; set; }
public int size { get; set; }
}
public class Surcharge
{
public decimal amount { get; set; }
public string type { get; set; }
}
public class Surcharges
{
public Surcharge Surcharge { get; set; }
public int size { get; set; }
}
public class ChargeableRateInfo
{
public NightlyRatesPerRoom NightlyRatesPerRoom { get; set; }
public Surcharges Surcharges { get; set; }
public decimal averageBaseRate { get; set; }
public decimal averageRate { get; set; }
public decimal commissionableUsdTotal { get; set; }
public string currencyCode { get; set; }
public decimal maxNightlyRate { get; set; }
public decimal nightlyRateTotal { get; set; }
public decimal surchargeTotal { get; set; }
public decimal total { get; set; }
}
public class CancelPolicyInfo
{
public string cancelTime { get; set; }
public string currencyCode { get; set; }
public int nightCount { get; set; }
public int percent { get; set; }
public int startWindowHours { get; set; }
public string timeZoneDescription { get; set; }
public int versionId { get; set; }
}
public class CancelPolicyInfoList
{
public List<CancelPolicyInfo> CancelPolicyInfo { get; set; }
}
public class RateInfo
{
public CancelPolicyInfoList CancelPolicyInfoList { get; set; }
public ChargeableRateInfo ChargeableRateInfo { get; set; }
public RoomGroup RoomGroup { get; set; }
public string cancellationPolicy { get; set; }
public int currentAllotment { get; set; }
public bool depositRequired { get; set; }
public bool guaranteeRequired { get; set; }
public bool nonRefundable { get; set; }
public string priceBreakdown { get; set; }
public string promo { get; set; }
public string promoType { get; set; }
public string rateChange { get; set; }
public string rateType { get; set; }
public decimal taxRate { get; set; }
}
public class RateInfos
{
public RateInfo RateInfo { get; set; }
public int size { get; set; }
}
public class ValueAdd
{
public string description { get; set; }
public string id { get; set; }
}
public class ValueAdds
{
public List<ValueAdd> ValueAdd { get; set; }
public int size { get; set; }
}
public class RoomImage
{
public string url { get; set; }
}
public class RoomImages
{
public RoomImage RoomImage { get; set; }
public int size { get; set; }
}
public class HotelRoomResponse
{
public BedTypes BedTypes { get; set; }
public RateInfos RateInfos { get; set; }
public RoomImages RoomImages { get; set; }
public ValueAdds ValueAdds { get; set; }
public string deepLink { get; set; }
public int minGuestAge { get; set; }
public int propertyId { get; set; }
public int quotedOccupancy { get; set; }
public int rateCode { get; set; }
public string rateDescription { get; set; }
public int rateOccupancyPerRoom { get; set; }
public int roomTypeCode { get; set; }
public string roomTypeDescription { get; set; }
public string smokingPreferences { get; set; }
public string supplierType { get; set; }
}
public class HotelRoomAvailabilityResponse
{
public List<HotelRoomResponse> HotelRoomResponse { get; set; }
public string arrivalDate { get; set; }
public string checkInInstructions { get; set; }
public string customerSessionId { get; set; }
public string departureDate { get; set; }
public string hotelAddress { get; set; }
public string hotelCity { get; set; }
public string hotelCountry { get; set; }
public int hotelId { get; set; }
public string hotelName { get; set; }
public string hotelStateProvince { get; set; }
public int numberOfRoomsRequested { get; set; }
public int size { get; set; }
public decimal tripAdvisorRating { get; set; }
public string tripAdvisorRatingUrl { get; set; }
public int tripAdvisorReviewCount { get; set; }
}
public class ExpediaHotelRoomAvailability
{
public HotelRoomAvailabilityResponse HotelRoomAvailabilityResponse { get; set; }
}
}
Could this possibly have something to do with the # symbols in the JSON and if so how do I get around this?
You can handle the # symbols named fields by providing their name using a [DataMember(Name=...)] attribute.
Unfortunately this mean you have to provide a [DataContract] attribute on your DTO, which means all the properties then become opt-in. So all properties will need to have [DataMember] to be included, which makes the DTO less readable.
So your NightlyRate DTO becomes:
[DataContract]
public class NightlyRate
{
[DataMember(Name="#baseRate")]
public string baseRate { get; set; }
[DataMember(Name="#promo")]
public string promo { get; set; }
[DataMember(Name="#rate")]
public string rate { get; set; }
}
And NightlyRatesPerRoom would be:
[DataContract]
public class NightlyRatesPerRoom
{
[DataMember]
public List<NightlyRate> NightlyRate { get; set; }
[DataMember(Name="#size")]
public int size { get; set; }
}
Obviously you will have to mark up the other DTOs as appropriate. I hope that helps.
I am trying to generate C# class using the JSON string from here http://json2csharp.com/ this works fine. But I can't parse the JSON to the object generated by the website.
Here is the JSON string
{
"searchParameters":{
"key":"**********",
"system":"urn:oid:.8"
},
"message":" found one Person matching your search criteria.",
"_links":{
"self":{
"href":"https://integration.rest.api.test.com/v1/person?key=123456&system=12.4.34.."
}
},
"_embedded":{
"person":[
{
"details":{
"address":[
{
"line":["5554519 testdr"],
"city":"testland",
"state":"TT",
"zip":"12345",
"period":{
"start":"2003-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"name":[
{
"use":"usual",
"family":["BC"],
"given":["TWO"],
"period":{
"start":"9999-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"gender":{
"code":"M",
"display":"Male"
},
"birthDate":"9999-02-03T00:00:00Z",
"identifier":[
{
"use":"unspecified",
"system":"urn:oid:2.19.8",
"key":"",
"period":{
"start":"9999-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"telecom":[
{
"system":"email",
"value":"test#test.com",
"use":"unspecified",
"period":{
"start":"9999-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"photo":[
{
"content":{
"contentType":"image/jpeg",
"language":"",
"data":"",
"size":0,
"hash":"",
"title":"My Picture"
}
}
]
},
"enrolled":true,
"enrollmentSummary":{
"dateEnrolled":"9999-02-07T21:39:11.174Z",
"enroller":"test Support"
},
"_links":{
"self":{
"href":"https://integration.rest.api.test.com/v1/person/-182d-4296-90cc"
},
"unenroll":{
"href":"https://integration.rest.api.test.com/v1/person/1b018dc4-182d-4296-90cc-/unenroll"
},
"personLink":{
"href":"https://integration.rest.api.test.com/v1/person/-182d-4296-90cc-953c/personLink"
},
"personMatch":{
"href":"https://integration.rest.api.commonwellalliance.org/v1/person/-182d-4296-90cc-/personMatch?orgId="
}
}
}
]
}
}
Here is the code I use to convert to the object.
JavaScriptSerializer js = new JavaScriptSerializer();
var xx = (PersonsearchVM)js.Deserialize(jsonstr, typeof(PersonsearchVM));
Is there any other wat to generate the object and parse?
I think you have some invalid characters in your JSON string. Run it through a validator and add the necessary escape characters.
http://jsonlint.com/
You aren't casting it to the right object. Cast it to the type RootObject.
Eg
JavaScriptSerializer js = new JavaScriptSerializer();
var xx = (RootObject)js.Deserialize(jsonstr, typeof(RootObject));
The code that json 2 csharp creates is this:
public class SearchParameters
{
public string key { get; set; }
public string system { get; set; }
}
public class Self
{
public string href { get; set; }
}
public class LinKs
{
public Self self { get; set; }
}
public class Period
{
public string start { get; set; }
public string end { get; set; }
}
public class Address
{
public List<string> line { get; set; }
public string city { get; set; }
public string __invalid_name__state { get; set; }
public string zip { get; set; }
public Period period { get; set; }
}
public class PerioD2
{
public string start { get; set; }
public string end { get; set; }
}
public class Name
{
public string use { get; set; }
public List<string> family { get; set; }
public List<string> given { get; set; }
public PerioD2 __invalid_name__perio
d { get; set; }
}
public class Gender
{
public string __invalid_name__co
de { get; set; }
public string display { get; set; }
}
public class Period3
{
public string start { get; set; }
public string __invalid_name__end { get; set; }
}
public class Identifier
{
public string use
{ get; set; }
public string system { get; set; }
public string key { get; set; }
public Period3 period { get; set; }
}
public class Period4
{
public string start { get; set; }
public string end { get; set; }
}
public class Telecom
{
public string system { get; set; }
public string value { get; set; }
public string use { get; set; }
public Period4 period { get; set; }
}
public class Content
{
public string contentType { get; set; }
public string language { get; set; }
public string __invalid_name__dat
a { get; set; }
public int size { get; set; }
public string hash { get; set; }
public string title { get; set; }
}
public class Photo
{
public Content content { get; set; }
}
public class Details
{
public List<Address> address { get; set; }
public List<Name> name { get; set; }
public Gender gender { get; set; }
public string birthDate { get; set; }
public List<Identifier> identifier { get; set; }
public List<Telecom> telecom { get; set; }
public List<Photo> photo { get; set; }
}
public class EnrollmentSummary
{
public string dateEnrolled { get; set; }
public string __invalid_name__en
roller { get; set; }
}
public class Self2
{
public string href { get; set; }
}
public class UnEnroll
{
public string href { get; set; }
}
public class PersonLink
{
public string href { get; set; }
}
public class PersonMatch
{
public string href { get; set; }
}
public class Links2
{
public Self2 self { get; set; }
public UnEnroll __invalid_name__un
enroll { get; set; }
public PersonLink personLink { get; set; }
public PersonMatch personMatch { get; set; }
}
public class Person
{
public Details details { get; set; }
public bool __invalid_name__e
nrolled { get; set; }
public EnrollmentSummary enrollmentSummary { get; set; }
public Links2 _links { get; set; }
}
public class Embedded
{
public List<Person> person { get; set; }
}
public class RootObject
{
public SearchParameters searchParameters { get; set; }
public string message { get; set; }
public LinKs __invalid_name___lin
ks { get; set; }
public Embedded _embedded { get; set; }
}
The following function will convert JSON into a C# class where T is the class type.
public static T Deserialise<T>(string json)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms); //
return obj;
}
}
You need a reference to the System.Runtime.Serialization.json namespace.
The function is called in the following manner;
calendarList = Deserialise<GoogleCalendarList>(calendarListString);
calendarlist being the C# class and calendarListString the string containing the JSON.