Reputation: 17
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?
Upvotes: 1
Views: 2860
Reputation: 17
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);
Upvotes: 0
Reputation: 12465
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"
}
}
}
Upvotes: 0
Reputation: 94
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; }
}
Upvotes: 2
Reputation: 7468
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)>
Upvotes: 0