Passing javascript map to json wcf service

I would like to pass an associative array to the json wcf service.

So, in JavaScript, I have something similar to this:

var map = { }; map['a'] = 1; map['b'] = 2; map['c'] = 3; 

And in my wcf service I want to expect Dictionary:

 [OperationContract][WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] public void setDictionary(Dictionary<string, int> myDictionary); 

But it sends the map as an [Object object], and does not serialize it, because "map" is actually just an object to which I assign properties.

Does anyone know how I can serialize it correctly to get it deserialized as a Dictionary object using the WCF service?

+7
source share
2 answers

By default, WCF does not represent Dictionary as JSON objects - instead, it presents them as arrays of key / value pairs. Therefore, in order to send this card to the WCF service, you will need to hide it accordingly (see the code below).

Another alternative is to use custom message formatting that knows how to populate dictionaries based on JSON objects. For more information about posters, check out this blog post .

This shows one way to pass this 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; namespace StackOverflow_15001755 { [ServiceContract] public class Service { static Dictionary<string, int> dictionary; [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] public void setDictionary(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 to call ajax):

 <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script type="text/javascript" src="scripts/jquery-1.7.2.js"></script> <script type="text/javascript" src="scripts/json2.js"></script> </head> <body> <script type="text/javascript"> function StackOverflow_15001755_Test() { function dictionaryToKVPArray(obj) { var data = []; for (var key in obj) { data.push({ Key: key, Value: obj[key] }); } return data; } function KVPArrayToDictionary(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> <input type="button" value="StackOverflow 15001755" onclick="StackOverflow_15001755_Test();" /><br /> <div id='result'></div><br /> <div id='result2'></div><br /> </body> </html> 
+5
source

I managed to get this working using JSON.stringify(map) to get a serialized version of the map. Then pass it to the WCF service as a string, not a dictionary, and deserialize it yourself 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)] public void doDictionaryStuff(string serializedMap); 

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

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

It is not perfect, but it works.

+4
source

All Articles