admin管理员组文章数量:1356588
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 wcf service I want to expect a 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] rather than serializing it because the 'map' is actually just an object I'm assigning properties to.
Does anyone know how I can serialize it to correctly to get it deserialized as a Dictionary object by the 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 wcf service I want to expect a 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] rather than serializing it because the 'map' is actually just an object I'm assigning properties to.
Does anyone know how I can serialize it to correctly to get it deserialized as a Dictionary object by the WCF service?
Share Improve this question asked Feb 21, 2013 at 12:00 LoghamLogham 4333 silver badges13 bronze badges 2-
1
Have you tried JSON.stringify function?
echo JSON.stringify(map);
should output a string:{"a": 1, "b": 2, "c": 3}
– Imperative Commented Feb 21, 2013 at 12:02 - It does but the wcf throws: The formatter threw an exception while trying to deserialize the message – Logham Commented Feb 21, 2013 at 12:13
2 Answers
Reset to default 5By 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;
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 for the ajax call):
<html xmlns="http://www.w3/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>
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)]
public void doDictionaryStuff(string serializedMap);
Deserializing it in the 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's not ideal, but does work.
本文标签: Pass a javascript map to json wcf serviceStack Overflow
版权声明:本文标题:Pass a javascript map to json wcf service - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744025529a2577977.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论