I try to deserialization a JSON like the following(Numbers like 93817 and 935812 are dynamically generated from a server. Can't be hard coded.):
{ "status":"1",
"list":{
"93817":{ "item_id":"93817",
"url":"http://url.com",
"title":"Page Title",
"time_updated":"1245626956",
"time_added":"1245626956",
"tags":"comma,seperated,list",
"state":"0"
},
"935812":{ "item_id":"935812",
"url":"http://google.com",
"title":"Google",
"time_updated":"1245626956",
"time_added":"1245626956",
"tags":"comma,seperated,list",
"state":"1"
} }}
Here is the code for deserialization:
responseGetList = e.Result.ToString(); //responseGetList is the JSON string
MemoryStream ms = new MemoryStream( Encoding.Unicode.GetBytes(responseGetList));
DataContractJsonSerializer serializer =
new DataContractJsonSerializer( typeof(List<ResponseItem>) );
ResponseItem li = (ResponseItem)serializer.ReadObject(ms);
And the following is the ResponseItem class:
namespace whatever
{
[DataContract]
public class ResponseItem
{
[DataMember(Name = "status")]
string status;
public string Status
{
get { return status; }
set { status = value; }
}
[DataMember(Name = "list")]
List<ListItem> list;
private List<ListItem> List
{
get { return list; }
set { list = value; }
}
}
public class ListItem
{
[DataMember]
List<Article> listArticle;
public List<Article> ListArticle
{
get { return listArticle; }
set { listArticle = value; }
}
}
}
public class Article
{
[DataMember(Name = "item_id")]
string item_id;
public string Item_id
{
get { return item_id; }
set { item_id = value; }
}
[DataMember(Name = "url")]
string url;
public string Url
{
get { return url; }
set { url = value; }
}
[DataMember(Name = "title")]
string title;
public string Title
{
get { return title; }
set { title = value; }
}
[DataMember(Name = "time_updated")]
string time_updated;
public string Time_updated
{
get { return time_updated; }
set { time_updated = value; }
}
[DataMember(Name = "time_added")]
string time_added;
public string Time_added
{
get { return time_added; }
set { time_added = value; }
}
[DataMember(Name = "tags")]
string tags;
public string Tags
{
get { return tags; }
set { tags = value; }
}
[DataMember(Name = "state")]
string state;
public string State
{
get { return state; }
set { state = value; }
}
}
I get InvalidCastException on 1ataContractJsonSerializer serializer =
new DataContractJsonSerializer( typeof(List<ResponseItem>) );, I think it is a JSON-Object mapping problem. Can any one help me?
Try using NewtonSoft's LINQ to Json, it's a way cleaner method to de/serialize json strings
ClassName class= new ClassName();
objectname = JsonConvert.DeserializeObject<ClassName>(responseGetList);
Use Json2C# to create the ClassName you need to have to be able to deserialize straight into an object.
You can use object.__ to call upon any of the results: example with your code:
object.list.(93817(you will have to cast this with a JsonProperty, because c# doesn't allow methods with solely numbers)).item_id = 93817
cleaner : object.list.thenameyougavethemethod.item_id
Good luck, if you have more questions, just add comments
EDIT : I parsed the json string and added JsonProperties to your specific Json String;
Just download the NewtonSoft .dll & don't forget to add a reference to your project ...
public class id93817
{
public string item_id { get; set; }
public string url { get; set; }
public string title { get; set; }
public string time_updated { get; set; }
public string time_added { get; set; }
public string tags { get; set; }
public string state { get; set; }
}
public class id935812
{
public string item_id { get; set; }
public string url { get; set; }
public string title { get; set; }
public string time_updated { get; set; }
public string time_added { get; set; }
public string tags { get; set; }
public string state { get; set; }
}
public class List
{
[JsonProperty("93817")]
public id93817 { get; set; }
[JsonProperty("935812")]
public id935812 { get; set; }
}
public class RootObject
{
public string status { get; set; }
public List list { get; set; }
}
Try switching to Json.NET for deserializing the object. It is less error prone and fragile (and yes, it's open source and works on the phone)>
The first item in the lists are incorrect. Your JSON shows "93817" and "935812" but those are not properties on your items. The first part of your JSON must be a property name. You're doing it right for "list" because it corresponds to the List property of ResponseItem. Change those numbers to "listArticle". I also second Shawn Wildermuth's suggestion for JSON.Net.
The JSON that is generated on the server should be serialized the same way that it is deserialized (ie: use the same framework to (de)serialize). If you are generating the JSON by hand, don't. You will have more problems than you need or want.
If you serialize the object, you should have the following:
{ "status":"1",
"list":{
"listArticle":{
"item_id":"93817",
"url":"http://url.com",
"title":"Page Title",
"time_updated":"1245626956",
"time_added":"1245626956",
"tags":"comma,seperated,list",
"state":"0"
},
"listArticle":{
"item_id":"935812",
"url":"http://google.com",
"title":"Google",
"time_updated":"1245626956",
"time_added":"1245626956",
"tags":"comma,seperated,list",
"state":"1"
}
}
}
Issue resolved by reading the source code of RIL# (http://rilsharp.codeplex.com/).
The problem is mainly mapping issue. Using Dictionary is the key resolution:
[DataContract]
public class ResponseItem
{
[DataMember(Name = "status")]
public ListStatus Status { get; set; }
[DataMember(Name = "since")]
public double Since { get; set; }
[DataMember(Name = "list")]
public Dictionary<string, RilListItem> items { get; set; }
public DateTime SinceDate
{
get
{
return UnixTime.ToDateTime(Since);
}
}
Then using Json.net to deserialize the JSON:
ResponseItem ri = new ResponseItem();
ri = JsonConvert.DeserializeObject<ResponseItem>(responseGetList);
Related
All - I've stumbled into a scenario that's causing me quite a bit of grief. I have a json structure (produced by gateio api) which on the face of it, looks super simple to deserialize into an object. the jsonTickerString looks like the below:
{
"method":"ticker.update",
"params":[
"BTC_USDT",
{
"period":86400,
"open":"46721.06",
"close":"48130.43",
"high":"48758.59",
"low":"46330.3",
"last":"48130.43",
"change":"2.95",
"quoteVolume":"2246.8399550054",
"baseVolume":"106183751.468785134437"
}
],
"id":null
}
However, this is proving to be deceptively funky when trying to push it into an object model. I derived the object model below and thought we were all set to go:
public partial class GateIoTicker
{
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("params")]
public List<ParamElement> Params { get; set; }
[JsonProperty("id")]
public object Id { get; set; }
}
public class ParamClass
{
[JsonProperty("period")]
public long Period { get; set; }
[JsonProperty("open")]
public string Open { get; set; }
[JsonProperty("close")]
public string Close { get; set; }
[JsonProperty("high")]
public string High { get; set; }
[JsonProperty("low")]
public string Low { get; set; }
[JsonProperty("last")]
public string Last { get; set; }
[JsonProperty("change")]
public string Change { get; set; }
[JsonProperty("quoteVolume")]
public string QuoteVolume { get; set; }
[JsonProperty("baseVolume")]
public string BaseVolume { get; set; }
}
public partial struct ParamElement
{
public string coinName;
public ParamClass quoteParams;
public static implicit operator ParamElement(ParamClass quoteparams)
{
return new ParamElement { quoteParams = quoteparams };
}
public static implicit operator ParamElement(string coinname)
{
return new ParamElement { coinName = coinname };
}
}
I then set about populating the object using the standard Json.Net approach:
var gateIoTicker = JsonConvert.DeserializeObject<GateIoTicker>(jsonTickerString);
However, although this correctly deserializes the string element in the "params" object, no amount of coersion will bring about a deserialization of the ParamClass object.
Am I missing something very obvious here?? I've spent an inordinate amount of time trying to figure this out and think it's now time to solicit some superior brain power.
Hope this scans as expected...
[Edit] - further to Serge's suggestion, i took his code and added it as a method on my GatIoTicker object. Would have preferred an option that desrializes using attributes, but this works perfectly. Refactored code looks like:
public partial class GateIoTicker
{
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("params")]
public List<ParamElement> Params { get; set; }
[JsonProperty("id")]
public object Id { get; set; }
public GateIoTicker FromJson(string json)
{
var jsonObject = JObject.Parse(json);
var pars = jsonObject["params"] as JArray;
var paramElement = new ParamElement();
foreach (var jObject in pars)
{
if (jObject.GetType().Name.ToString() == "JValue") paramElement.ParamName = ((JValue)jObject).ToString();
else
{
paramElement.ParamBody = jObject.ToObject<ParamClass>();
}
}
GateIoTicker gateIoTicker = new GateIoTicker { Params = new List<ParamElement>() };
gateIoTicker.Id = (string)jsonObject["Id"];
gateIoTicker.Method = (string)jsonObject["method"];
gateIoTicker.Params.Add(paramElement);
return gateIoTicker;
}
}
public partial class ParamElement
{
public string ParamName { get; set; }
public ParamClass ParamBody {get; set;}
}
thanks again for the suggestions and nudges. seasons greetings
Try this, it was tested in Visual studio
var jsonObject = JObject.Parse(json);
var pars = jsonObject["params"] as JArray;
var paramElement = new ParamElement();
foreach (var jObject in pars)
{
if (jObject.GetType().Name.ToString() == "JValue") paramElement.ParamName = ((JValue)jObject).ToString();
else
{
paramElement.ParamBody=jObject.ToObject<ParamClass>();
}
}
GateIoTicker gateIoTicker = new GateIoTicker {Params= new List<ParamElement>()};
gateIoTicker.Id= (string) jsonObject["Id"];
gateIoTicker.Method= (string) jsonObject["method"];
gateIoTicker.Params.Add(paramElement);
ParamElement class
public partial class ParamElement
{
public string ParamName { get; set; }
public ParamClass ParamBody {get; set;}
}
I have the below classes.
public class Source { public string ConfigData { get; set; } }
public class Configuration { public IEnumerable<IpAddress> IpAddresses { get; set; } }
public class IpAddress
{
public string Start { get; set; }
public string End { get; set; }
public bool IsValid { get; set; }
public Family IPFamily { get; set; }
}
First, I am getting the ConfigData as string from a source and deserializing it below:
var storedIPAddresses = JsonConvert.DeserializeObject<Configuration>( source.ConfigData).IpAddresses;
Next I am doing some checks, which essentially sets the values of IsValid and IPFamily.
if (storedIPAddresses.Any())
{
foreach (var ipDetail in storedIPAddresses)
{
if (!string.IsNullOrEmpty(ipDetail.StartIpAddress) && !string.IsNullOrEmpty(ipDetail.EndIpAddress))
{
if (bla == blabla)
{
ipDetail.IsValid = true;
ipDetail.IPFamily = IPAddressFamily.IPV4;
}
}
}
}
Lastly, I am supposed to return the souce object by chucking in the updated storedIPAddresses inside, which is where I need some guidance.
I am able to do in following way; but looking for any more elegant way?
var config = new Configuration();
config = JsonConvert.DeserializeObject<Configuration>(source.ConfigData);
config.IpAddresses = storedIPAddresses;
source.ConfigData = JsonConvert.SerializeObject(config);
return source;
I have a string stream returning JSON data from and API that looks like this:
"{\"Recs\":
[
{\"EID\":\"F67_24_6\",\"ReturnPeriod\":\"1\",\"GageStation\":\"NA\"},
{\"EID\":\"T67_24_6\",\"ReturnPeriod\":\"2.37\",\"GageStation\":\"Magueyes Island\"},
{\"EID\":\"R67_24_6\",\"ReturnPeriod\":\"1\",\"GageStation\":\"50147800\"}
]}"
I am trying to deserialize it to return this:
{"Recs":[
{"EID":"F67_24_6","ReturnPeriod":"1","GageStation":"NA"},
{"EID":"T67_24_6","ReturnPeriod":"2.37","GageStation":"Magueyes Island"},
{"EID":"R67_24_6","ReturnPeriod":"1","GageStation":"50147800"}
]}
I am using these public classes to structure the return:
public class New_Events_Dataset
{
public string EID { get; set; }
public string ReturnPeriod { get; set; }
public string GageStation { get; set; }
}
public class NewRootObject
{
public List<New_Events_Dataset> Reqs { get; set; }
}
When I try to apply this later, I basically get a return of {"Reqs":null}. What am I doing wrong here?
var jsonResponse = JsonConvert.DeserializeObject<NewRootObject>(strresult);
string json = new JavaScriptSerializer().Serialize(jsonResponse);
return json;
I think Reqs should be Recs:
public class NewRootObject
{
public List<New_Events_Dataset> Reqs { get; set; }
}
try:
public class NewRootObject
{
public List<New_Events_Dataset> Recs { get; set; }
}
Rename Reqs to Recs and create default constructor of class and instantiate Recs list
public class NewRootObject
{
List<New_Events_Dataset> Recs { get; set; }
public NewRootObject()
{
Recs = new List<New_Events_Dataset>();
}
}
My project has a 3rd party web API that returns a json string in the following format (including the starting and ending curly braces):
{
"866968030210604":{
"dt_server":"2019-02-07 12:21:27",
"dt_tracker":"2019-02-07 12:21:27",
"lat":"28.844968",
"lng":"76.858502",
"altitude":"0",
"angle":"154",
"speed":"9",
"params":{
"pump":"0",
"track":"1",
"bats":"1",
"acc":"0",
"batl":"4"
},
"loc_valid":"1"
},
"866968030221205":{
"dt_server":"2019-02-07 12:20:24",
"dt_tracker":"2019-02-07 12:19:41",
"lat":"28.845904",
"lng":"77.096063",
"altitude":"0",
"angle":"0",
"speed":"0",
"params":{
"pump":"0",
"track":"1",
"bats":"1",
"acc":"0",
"batl":"4"
},
"loc_valid":"1"
},
"866968030212030":{
"dt_server":"0000-00-00 00:00:00",
"dt_tracker":"0000-00-00 00:00:00",
"lat":"0",
"lng":"0",
"altitude":"0",
"angle":"0",
"speed":"0",
"params":null,
"loc_valid":"0"
}
}
I want to deserialize it into a c# class object for further processing. I made the following class structure for the same:
class Params
{
public string pump { get; set; }
public string track { get; set; }
public string bats { get; set; }
public string acc { get; set; }
public string batl { get; set; }
}
class GPSData
{
public string dt_server { get; set; }
public string dt_tracker { get; set; }
public string lat { get; set; }
public string lng { get; set; }
public string altitude { get; set; }
public string angle { get; set; }
public string speed { get; set; }
public Params ObjParams { get; set; }
public string loc_valid { get; set; }
}
and I am trying the following code to deserialize:
JavaScriptSerializer jSerObj = new JavaScriptSerializer();
List<GPSData> lstGPSData = (List<GPSData>)jSerObj.Deserialize(json, typeof(List<GPSData>));
But every time it is showing NULL values assigned to each property of the class after the Deserialize() method is called. Please help me on this.
Your json is not in list format so deserializing to List<> isn't work
So you need to deserialize it into Dictionary<string, GPSData> like
JavaScriptSerializer jSerObj = new JavaScriptSerializer();
Dictionary<string, GPSData> lstGPSData = (Dictionary<string, GPSData>)jSerObj.Deserialize(json, typeof(Dictionary<string, GPSData>));
Usage:
foreach (var item in lstGPSData)
{
string key = item.Key;
GPSData gPSData = item.Value;
}
Also, you can list all your GPSData from above dictionary like,
List<GPSData> gPSDatas = lstGPSData.Values.ToList();
Output: (From Debugger)
Im having with the content. it is auto increment.
the result is static but the content is dynamic.
I'm using a hardcoded array in catching the return string from the web. Can anyone json decoder in converting the returned string to c# object
This is the returned string from web:
{
"result":{
"count":"3"
},
"content_1":{
"message_id":"23",
"originator":"09973206870",
"message":"Hello",
"timestamp":"2016-09-14 13:59:47"
},
"content_2":{
"message_id":"24",
"originator":"09973206870",
"message":"Test again.",
"timestamp":"2016-09-14 14:49:14"
},
"content_3":{
"message_id":"25",
"originator":"09973206870",
"message":"Another message",
"timestamp":"2016-09-14 14:49:20"
}
}
On site json2csharp.com you can generate classes for JSON data.
Generated classes needs some improvements and can look like:
public class Result
{
public string count { get; set; }
}
public class Content
{
public string message_id { get; set; }
public string originator { get; set; }
public string message { get; set; }
public string timestamp { get; set; }
}
public class RootObject
{
public Result result { get; set; }
public Content content_1 { get; set; }
public Content content_2 { get; set; }
public Content content_3 { get; set; }
}
And using JSON.NET you can deserialize it:
public class Program
{
static public void Main()
{
string json = "{ \"result\":{ \"count\":\"3\" }, \"content_1\":{ \"message_id\":\"23\", \"originator\":\"09973206870\", \"message\":\"Hello\", \"timestamp\":\"2016-09-14 13:59:47\" }, \"content_2\":{ \"message_id\":\"24\", \"originator\":\"09973206870\", \"message\":\"Test again.\", \"timestamp\":\"2016-09-14 14:49:14\" }, \"content_3\":{ \"message_id\":\"25\", \"originator\":\"09973206870\", \"message\":\"Another message\", \"timestamp\":\"2016-09-14 14:49:20\" } }";
RootObject ro = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(ro.content_1.message_id);
Console.WriteLine(ro.content_2.message_id);
}
}