Skip to content Skip to sidebar Skip to footer

Pass A Javascript Map To Json Wcf Service

I would like to pass an associative array to a json wcf service. So in JavaScript I have something akin to this: var map = { }; map['a'] = 1; map['b'] = 2; map['c'] = 3; And in my

Solution 1:

By default, WCF does not represent Dictionary as JSON objects - it represents them as arrays of key/value pairs instead. So to send that map to the WCF service, you'll need to covert it appropriately (see code below).

Another alternative is to use a custom message formatter, which knows how to populate dictionaries based on JSON objects. For more information on message formatters, check this blog post.

This shows one way of passing that object to your service:

Service.svc:

<%@ ServiceHost Language="C#"Debug="true" Service="StackOverflow_15001755.Service"
                CodeBehind="StackOverflow_15001755.svc.cs" 
                Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

Service.svc.cs:

using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;

namespaceStackOverflow_15001755
{
    [ServiceContract]
    publicclassService
    {
        static Dictionary<string, int> dictionary;

        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        publicvoidsetDictionary(Dictionary<string, int> myDictionary)
        {
            dictionary = myDictionary;
        }

        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public Dictionary<string, int> getDictionary()
        {
            return dictionary;
        }
    }
}

Test.html (HTML/JS code, using jQuery for the ajax call):

<htmlxmlns="http://www.w3.org/1999/xhtml"><head><scripttype="text/javascript"src="scripts/jquery-1.7.2.js"></script><scripttype="text/javascript"src="scripts/json2.js"></script></head><body><scripttype="text/javascript">functionStackOverflow_15001755_Test() {
            functiondictionaryToKVPArray(obj) {
                var data = [];
                for (var key in obj) {
                    data.push({ Key: key, Value: obj[key] });
                }

                return data;
            }

            functionKVPArrayToDictionary(arr) {
                var result = {};
                arr.forEach(function (item) {
                    result[item.Key] = item.Value;
                });

                return result;
            }

            var map = {};
            map['a'] = 1;
            map['b'] = 2;
            map['c'] = 3;
            var data = dictionaryToKVPArray(map);

            var baseUrl = "/StackOverflow_15001755.svc";
            $.ajax({
                type: 'POST',
                url: baseUrl + '/setDictionary',
                contentType: 'application/json',
                data: JSON.stringify({ myDictionary: data }),
                success: function (result) {
                    $('#result').text('Sent the dictionary');
                    $.ajax({
                        type: 'GET',
                        url: baseUrl + '/getDictionary',
                        success: function (result) {
                            var newMap = KVPArrayToDictionary(result);
                            $('#result2').text(JSON.stringify(newMap));
                        }
                    });
                }
            });
        }
    </script><inputtype="button"value="StackOverflow 15001755"onclick="StackOverflow_15001755_Test();" /><br /><divid='result'></div><br /><divid='result2'></div><br /></body></html>

Solution 2:

I managed to get this working by using JSON.stringify(map) to get a serialized version of the map. Then passing it to WCF service as a string rather than a Dictionary and deserializing it myself in the method using the Json.Net framework.

Serialized Map:

{'a':'0','b':'1','c':'2'}

WCF Service:

[OperationContract][WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
publicvoiddoDictionaryStuff(string serializedMap);

Deserializing it in the WCF service using the Json.Net framework:

publicvoiddoDictionaryStuff(string serializedMap)
{
    Dictionary<string, int> map = JsonConvert.DeserializeObject<Dictionary<string,int>>(serializedMap);
    //do stuff with the dictionary.
}

It's not ideal, but does work.

Post a Comment for "Pass A Javascript Map To Json Wcf Service"