I have a simple key/value list in JSON being sent back to ASP.NET via POST. Example:
{ "key1": "value1", "key2": "value2"}
I AM NOT TRYING TO DESERIALIZE INTO STRONGLY-TYPED .NET OBJECTS
I simply need a plain old Dictionary(Of String, String), or some equivalent (hash table, Dictionary(Of String, Object), old-school StringDictionary--hell, a 2-D array of strings would work for me.
I can use anything available in ASP.NET 3.5, as well as the popular Json.NET (which I'm already using for serialization to the client).
Apparently neither of these JSON libraries have this forehead-slapping obvious capability out of the box--they are totally focused on reflection-based deserialization via strong contracts.
Any ideas?
Limitations:
- I don't want to implement my own JSON parser
- Can't use ASP.NET 4.0 yet
- Would prefer to stay away from the older, deprecated ASP.NET class for JSON
I did discover .NET has a built in way to cast the JSON string into a
Dictionary<String, Object>
via theSystem.Web.Script.Serialization.JavaScriptSerializer
type in the 3.5System.Web.Extensions
assembly. Use the methodDeserializeObject(String)
.I stumbled upon this when doing an ajax post (via jquery) of content type 'application/json' to a static .net Page Method and saw that the method (which had a single parameter of type
Object
) magically received this Dictionary.You could use Tiny-JSON
Edit: This works, but the accepted answer using Json.NET is much more straightforward. Leaving this one in case someone needs BCL-only code.
It’s not supported by the .NET framework out of the box. A glaring oversight – not everyone needs to deserialize into objects with named properties. So I ended up rolling my own:
Called with:
Sorry for the mix of C# and VB.NET…
It seems all of these answers here just assume you can get that little string out of a bigger object... for people looking to simply deserealize a large object with such a dictionary somewhere inside the mapping, and who are using the
System.Runtime.Serialization.Json
DataContract system, here's a solution:An answer on gis.stackexchange.com had this interesting link. I had to recover it with archive.org, but it offers a pretty much perfect solution: a custom
IDataContractSurrogate
class in which you implement exactly your own types. I was able to expand it easily.I made a bunch of changes in it, though. Since the original source is no longer available, I'll post the entire class here:
To add new supported types to the class, you just need to add your class, give it the right constructors and functions (look at
SurrogateDictionary
for an example), make sure it inheritsJsonSurrogateObject
, and add its type mapping to theKnownTypes
dictionary. The included SurrogateDictionary can serve as basis for anyDictionary<String,T>
types where T is any type that does deserialize correctly.Calling it is really simple:
Note that for some reason this thing has trouble using key strings which contain spaces; they were simply not present in the final list. Might just be it's simply against json specs and the api I was calling was poorly implemented, mind you; I dunno. Anyway, I solved this by regex-replacing them with underscores in the raw json data and fixing the dictionary after the deserialization.
I just implemented this in RestSharp. This post was helpful to me.
Besides the code in the link, here is my code. I now get a
Dictionary
of results when I do something like this:Be mindful of the sort of JSON you're expecting - in my case, I was retrieving a single object with several properties. In the attached link, the author was retrieving a list.
If you're after a lightweight, no-added-references kind of approach, maybe this bit of code I just wrote will work (I can't 100% guarantee robustness though).
[I realise that this violates the OP Limitation #1, but technically, you didn't write it, I did]