【问题标题】:Pass a javascript map to json wcf service将 javascript 映射传递给 json wcf 服务
【发布时间】:2013-02-06 17:55:58
【问题描述】:

我想将关联数组传递给 json wcf 服务。

所以在 JavaScript 中我有类似的东西:

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

在我的 wcf 服务中,我希望有一个字典:

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

但它将地图作为 [Object object] 发送而不是序列化它,因为“地图”实际上只是我正在为其分配属性的对象。

有谁知道我如何正确序列化它以使其被 WCF 服务反序列化为 Dictionary 对象?

【问题讨论】:

  • 你试过JSON.stringify函数吗? echo JSON.stringify(map); 应该输出一个字符串:{"a": 1, "b": 2, "c": 3}
  • 确实可以,但是 wcf 抛出:格式化程序在尝试反序列化消息时抛出异常

标签: javascript json wcf dictionary map


【解决方案1】:

默认情况下,WCF 不将 Dictionary 表示为 JSON 对象 - 而是将它们表示为键/值对数组。因此,要将地图发送到 WCF 服务,您需要适当地对其进行转换(请参见下面的代码)。

另一种选择是使用自定义消息格式化程序,它知道如何根据 JSON 对象填充字典。有关消息格式化程序的更多信息,请查看此blog post

这显示了将该对象传递给您的服务的一种方式:

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 代码,使用 jQuery 进行 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>

【讨论】:

  • 您的 dictionaryToKVPArray() 方法正是我所需要的!谢谢 =) 标记为答案,因为它准确地显示了如何将正确的数据传递给 WCF 服务以反序列化 Dictionary 对象,以及将其重新返回到 javascript!
【解决方案2】:

我设法通过使用JSON.stringify(map) 来获取地图的序列化版本来完成这项工作。然后将其作为字符串而不是字典传递给 WCF 服务,并在方法中使用 Json.Net framework 自行反序列化它。

序列化地图:

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

WCF 服务:

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

在 WCF 服务中使用 Json.Net framework 反序列化它:

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

这并不理想,但确实有效。

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多