I've got the following piece of JSON:
[{
"name": "numToRetrieve",
"value": "3",
"label": "Number of items to retrieve:",
"items": {
"1": "1",
"3": "3",
"5": "5"
},
"rules": {
"range": "1-2"
}
},
{
"name": "showFoo",
"value": "on",
"label": "Show foo?"
},
{
"name": "title",
"value": "Foo",
"label": "Foo:"
}]
All in one line version (suitable for a string literal):
[{\"name\":\"numToRetrieve\",\"value\":\"3\",\"label\":\"Number of items to retrieve:\",\"items\":{\"1\":\"1\",\"3\":\"3\",\"5\":\"5\"},\"rules\":{\"range\":\"1-2\"}},{\"name\":\"showFoo\",\"value\":\"on\",\"label\":\"Show foo?\"},{\"name\":\"title\",\"value\":\"Foo\",\"label\":\"Foo:\"}]
In the above example, name
, value
, and label
are required but items
and rules
are optional.
Here's the class I'm trying to deserialize into:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace foofoo
{
[DataContract]
public sealed class FooDef
{
[DataMember(Name = "name", IsRequired = true)]
public string Name { get; set; }
[DataMember(Name = "value", IsRequired = true)]
public string Value { get; set; }
[DataMember(Name = "label", IsRequired = true)]
public string Label { get; set; }
[DataMember(Name = "items", IsRequired = false)]
public Dictionary<string, string> Items { get; set; }
[DataMember(Name = "rules", IsRequired = false)]
public Dictionary<string, string> Rules { get; set; }
}
}
Here's the code I use to deserialize:
var json = new DataContractJsonSerializer(typeof(List<FooDef>));
var bar = "[{\"name\":\"numToRetrieve\",\"value\":\"3\",\"label\":\"Number of items to retrieve:\",\"items\":{\"1\":\"1\",\"3\":\"3\",\"5\":\"5\"},\"rules\":{\"range\":\"1-2\"}},{\"name\":\"showFoo\",\"value\":\"on\",\"label\":\"Show foo?\"},{\"name\":\"title\",\"value\":\"Foo\",\"label\":\"Foo:\"}]";
var stream = new MemoryStream(Encoding.UTF8.GetBytes(bar));
var foo = json.ReadObject(stream);
stream.Close();
Everything goes reasonably well except that items
and rules
are empty for the first FooDef
pass. I have tried everything under the sun to try and get them populated: custom classes, NameValueCollection
, KeyValuePair<string, string>
, List
of both of the latter, and every other collection that seemed to apply. [EDIT: I forgot to try Hashtable
, which seemed like an obvious candidate. Didn't work.]
The problem, as I see it, is that the key piece under items
and rules
is open-ended. That is, it's not always going to be called range
or 3
. Any advice or ideas?
IMHO there is no way to deserialize the JSON string you provided into a .NET class using DataContractJsonSerializer.
The problem comes from the way DataContractJsonSerializer serializes dictionaries. You could use an alternative serializer such as Json.NET (which I strongly recommend) or JavaScriptSerializer (I think it was deprecated in favor of DataContractJsonSerializer but it will work for your scenario).
You can also read these rants.
Documentation: Serializing Collections - Json.NET
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/071f73bb-e141-4a68-ae61-05635382934f
Check this article out - it solved my problem almost perfectly. I had to change their object[] Type to a string, but i'm only using strings:string type Key/Value pairs, so no problems there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With