Brandon
Brandon

Reputation: 10953

WCF - How to use JavascriptSerializer as my Deserializer?

I do not like how the DataContractSerializer handles my Dictionary deserialization. My methods all return a Stream and I use the JavascriptDeserializer to return the JSON I want, but this does not help me with a Dictionary is one of the POST parameters.

The JavascriptSerializer handles Dictionary's like such:

{"myKey1":"myValue1", "myKey2":"myValue2"}

The DataContractSerializer does this:

[{"Key":"myKey1", "Value":"myValue1"}, {"Key":"myKey2", "Value":"myValue2"}]

The problem with this, is our Android and iPhone apps are puking generating the code natively and our AJAX calls are failing.

Any easy way to do this or a way to get around Microsoft's terrible Dictionary deserialization?

Upvotes: 3

Views: 2059

Answers (2)

Romain Meresse
Romain Meresse

Reputation: 3044

I had the same problem. I solved it by using a custom Dictionary (actually a wrapper) implementing ISerializable.

[Serializable]
public class CustomDictionary: ISerializable
{
    /// <summary>
    /// Inner object.
    /// </summary>        
    private Dictionary<string, string> innerDictionary;

    public CustomDictionary()
    {
        innerDictionary = new Dictionary<string, string>();
    }

    public CustomDictionary(IDictionary<string, string> dictionary)
    {
        innerDictionary = new Dictionary<string, string>(dictionary);
    }

    public Dictionary<string, string> InnerDictionary
    {
        get { return this.innerDictionary; }
    }

    //Used when deserializing
    protected CustomDictionary(SerializationInfo info, StreamingContext context)
    {
        if (object.ReferenceEquals(info, null)) throw new ArgumentNullException("info");
        innerDictionary = new Dictionary<string, string>();
        foreach (SerializationEntry entry in info)
        {
            innerDictionary.Add(entry.Name, entry.Value as string);
        }
    }

    //Used when serializing
    protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (!object.ReferenceEquals(info, null))
        {
            foreach (string key in innerDictionary.Keys)
            {
                string value = innerDictionary[key];
                info.AddValue(key, value);
            }
        }
    }

    //Add methods calling InnerDictionary as necessary (ContainsKey, Add, etc...)
}

Upvotes: 2

Related Questions