AdvApp
AdvApp

Reputation: 1170

Deserialize JSON with dictionary as attribute results in null .NET Dictionary<string,string>

I have a WCF web service method defined where one of the parameters dict is a Dictionary<string,string>:

public Models.ActEntry Create(string userName, int codeNo, int typeNo, int relatedPkey, DateTime createTime, string info, Dictionary<string, string> dict)

The JSON being supplied to IIS is below (NOTE: The value for sUser is supplied by the authentication layer):

{"codeNo":100,"typeNo":1,"relatedPkey":269222839,"createTime":"\/Date(1416002315864)\/","info":"something","dict":{"one":"first","two":"second","three":"third"}}

The JSON is happily deserialized without error but the value of dict is null (Count = 0). All the other attributes are deserialized properly. I can clearly see in the trace logs that IIS recognizes dict and correctly types it as an object but when I look at the Dictionary<string,string> variable dict in the method, it is null.

[HttpRequest] Method            POST
[HttpRequest] Content-Length    161
[HttpRequest] Content-Type      application/json; charset=utf-8
[HttpRequest] Authorization     Basic ZHNcYmFybmVzcjpSZWN0MWYxZXI=
[HttpRequest] Expect            100-continue
[HttpRequest] Host              **************
[HttpRequest] X-FECTransaction  63dc8855-e55d-48b0-b31b-ec44ea52b56e
[root] [root] type              object
[root] [codeNo] type            number
[root] codeNo                   100
[root] [typeNo] type            number
[root] typeNo                   1
[root] [relatedPkey] type       number
[root] relatedPkey              269222839
[root] [info] type              string
[root] info                     something
[root] [createTime] type        string
[root] createTime               /Date(1416002315864)/
[root] [dict] type              object
[root] [one] type               string 
[root] one                      first 
[root] [two] type               string
[root] two                      second 
[root] [three] type             string 
[root] three                    third

Upvotes: 0

Views: 205

Answers (2)

Naha
Naha

Reputation: 536

This is done in the DataContract Serializer. Maybe you can use it: Add to DataContract-class DataMember attribute. Then use KnownType attributes for expected types used for object. in the following example I use either int or bool in the collection :

[DataContract]
    [KnownType(typeof(int[]))]
    [KnownType(typeof(bool[]))]
    public class CompositeType
    {
        [DataMember]
        public object UsedForKnownTypeSerializationObject;

    [DataMember]
    public string StringValue
    {
        get;
        set;
    }
    [DataMember]
    public Dictionary<string, object> Parameters
    {
        get;
        set;
    }
}

Upvotes: 1

AdvApp
AdvApp

Reputation: 1170

Providing this for future reference: According to the paragraph below (from Stand-Alone JSON Serialization), it appears WCF cannot directly deserialize a Dictionary<>:

Dictionaries are not a way to work directly with JSON. Dictionary may not be supported in the same way in WCF as expected from working with other JSON technologies. For example, if "abc" is mapped to "xyz" and "def" is mapped to 42 in a dictionary, the JSON representation is not {"abc":"xyz","def":42} but is [{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}] instead.

I confirmed that the .Serialization.JavaScriptSerializer handles dictionaries just fine. But the deserializer in WCF does not. Not sure why -- or why this has never been addressed -- but there you are. I found several articles with implementation of alternative deserializers but chose not to go that route.

Upvotes: 0

Related Questions