2

They seem to be the same thing at the first look. Because JsonObject : IDictionary<string, string>. However, when I try to deserialize the follow sample data, I get different results:

 var str1 = "{\"employees\": [" +
 "{ \"firstName\":\"John\" , \"lastName\":\"Doe\" }, " +
 "{ \"firstName\":\"Anna\" , \"lastName\":\"Smith\" }, " +
 "{ \"firstName\":\"Peter\" , \"lastName\":\"Jones\" }" +
 "]}";
//first try
public static JsonObject DeserializeJsonString(this string s) {
 return JsonObject.Parse(s);
}
//second try
public static T DeserializeJson<T>(this string s) where T : class {
 return JsonSerializer.DeserializeFromString<T>(s);
}

First try JsonObject.Parse():

  • works fine and parse the object correctly.

Second try JsonSerializer.DeserializeFromString<Dictionary<string, string>>():

  • gives me key value pair of "employees" and "[{" which seems to be the beginning fragment of the the actual value and the rest of the data chunk is missing.

Why do I have bad data in the 2nd way?

EDIT -------------------------------------------------------

NO LONGER AN ISSUE.

Latest version of SS has patched this problem. Now it can parse Dictionary<string, string> just fine.

asked Oct 27, 2013 at 11:35

2 Answers 2

3
//Source code in ServiceStack.Text -> DeserializeDictionary.cs 
//Line 89
//if type is JsonObject : Dictionary<string, string>
 var mapKey = keyValue;
 var mapValue = elementValue;
//Line 145
//if type is Dictionary<string, string>
 var mapKey = Serializer.UnescapeString(keyValue);
 var mapValue = Serializer.UnescapeString(elementValue);

That's why:

var a = JsonSerializer.DeserializeFromString<Dictionary<string, string>>():
//returns <"key", "[{"> incorrect value
var b = JsonSerializer.DeserializeFromString<JsonObject>();
//returns <"key","[{...}]"> correct value

JsonObject is inherited from Dictionary<string, string>, but it is assigned a different meaning than a normal Dictionary<string, string>to have special treatment. To me 'a' and 'b' should return the same answer, either both works, or both don't work. Now 'a' is broken and 'b' works, I personally think this is a logical error.

answered Oct 27, 2013 at 23:08
1
  • It's parsed differently by design, Dictionary<string,string> is expecting JSON string values which get un-escaped, whilst JsonObject assumes that you want to dynamically parse JSON so it doesn't attempt to un-escape the raw value as a JSON string - letting you further dynamically parse the JSON object graph. Commented Oct 28, 2013 at 3:17
1

I would ask myself why the second call is allowed at all.

For Dictionary<string, string> I would expect a JSON string to look like { "key1": "val1", ...} but it is { "key1": not a string, ...} instead. I would expect it to fail (or return null) because of invalid or unexpected JSON format.

answered Oct 27, 2013 at 14:28
6
  • Hmm, your answer didn't cover it... JsonObject is Dictionary<string, string>, right? and JsonObject.Parse(string json) { return JsonSerializer.DeserializeFromString<JsonObject>(json);} from SS source code, right? why does that work? Commented Oct 27, 2013 at 21:58
  • @Tom Sorry, I missed that you're using the ServiceStack implementation. Usually a JsonObject implements something like IDictionary<string, JsonValue>. I think they got reasons for their decision (maybe my answer reflects that... maybe). That's something you should ask the actual developers. Commented Oct 27, 2013 at 23:16
  • np thanks for trying :) I found out the reason, thinking how to deal with it. Please see my answer above Commented Oct 27, 2013 at 23:19
  • I see that you're getting different results there, but I think that decision for this was made on purpose. JsonObject != string Dictionary (it's just misleading that JsonObject extends that dictionary). I could try to explain my assumption in my answer why they decided so (and why I agree) but I think the actual developers know better... Commented Oct 27, 2013 at 23:30
  • 1
    my libraries were 6+ months old, I "update all" nuget and it fixed the problem, now 'a' and 'b' both works Commented Oct 28, 2013 at 0:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.