views:

3921

answers:

4

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:

  1. I don't want to implement my own JSON parser
  2. Can't use ASP.NET 4.0 yet
  3. Would prefer to stay away from the older, deprecated ASP.NET class for JSON
+3  A: 

Take a look at the System.Runtime.Serialization.Json namespace. It has the DataContractJsonSerializer class that can be of help in your case.

Also, take a look at http://www.codeplex.com/Json

desigeek
Uhm... exactly the *wrong* answer. I don't need "contract"-driven deserialization, I just need a dictionary back, which apparently isn't supported from what I can tell. And I already said in the OP that I'd be happy to use the JSon.NET library, which I'm already using, but again, can't find examples of how to get back a dictionary.
richardtallent
Why the down vote? I said 'take a look' and that 'it can be of help'. Not that that's the answer. It was just meant to be a pointer. And maybe you should update your question to better indicate that you don't need contract driven serialization. Also, "james newton kings" library doesn't mean much because most people imo don't know whether thats the one of codeplex...
desigeek
I appreciate the attempt, but the title of the question, as well as the paragraph immediately after the sample JSON clearly explains that I'm not trying to deserialize a specific class, I need a plain old dictionary with both a string key and value. Will adjust to refer to Json.NET.
richardtallent
+1  A: 

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:

<Serializable()> Public Class StringStringDictionary
    Implements ISerializable
    Public dict As System.Collections.Generic.Dictionary(Of String, String)
    Public Sub New()
        dict = New System.Collections.Generic.Dictionary(Of String, String)
    End Sub
    Protected Sub New(info As SerializationInfo, _
          context As StreamingContext)
        dict = New System.Collections.Generic.Dictionary(Of String, String)
        For Each entry As SerializationEntry In info
            dict.Add(entry.Name, DirectCast(entry.Value, String))
        Next
    End Sub
    Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData
        For Each key As String in dict.Keys
            info.AddValue(key, dict.Item(key))
        Next
    End Sub
End Class

Called with:

string MyJsonString = "{ \"key1\": \"value1\", \"key2\": \"value2\"}";
System.Runtime.Serialization.Json.DataContractJsonSerializer dcjs = new
  System.Runtime.Serialization.Json.DataContractJsonSerializer(
    typeof(StringStringDictionary));
System.IO.MemoryStream ms = new
  System.IO.MemoryStream(Encoding.UTF8.GetBytes(MyJsonString));
StringStringDictionary myfields = (StringStringDictionary)dcjs.ReadObject(ms);
Response.Write("Value of key2: " + myfields.dict["key2"]);

Sorry for the mix of C# and VB.NET...

richardtallent
Crispy's approach does this more simply:
Coder 42
[TestMethod] public void TestSimpleObject() { const string json = @"{""Name"":""Bob"",""Age"":42}"; var dict = new JavaScriptSerializer().DeserializeObject(json) as IDictionary<string, object>; Assert.IsNotNull(dict); Assert.IsTrue(dict.ContainsKey("Name")); Assert.AreEqual("Bob", dict["Name"]); Assert.IsTrue(dict.ContainsKey("Age")); Assert.AreEqual(42, dict["Age"]); }
Coder 42
+6  A: 

Json.NET does this...

string json = @"{""key1"":""value1"",""key2"":""value2""}";

Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
James Newton-King
Awesome, thanks James! I couldn't find an equivalent example in the Json.NET online help, glad it was as simple as I suspected it should be.
richardtallent
+8  A: 

I did discover .NET has a built in way to cast the JSON string into a Dictionary<String, Object> via the System.Web.Script.Serialization.JavaScriptSerialize type in the 3.5 System.Web.Extensions assembly. Use the method DeserializeObject(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.

Crispy

related questions