2013-02-21 2 views
7

json wcfサービスに連想配列を渡したいと思います。 json wcfサービスにjavascriptマップを渡す

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

そして、私のWCFサービスで

は、私が辞書を期待したい:だから、JavaScriptで

私はこれに似た何かを持っている

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

をしかし、それは[Objectオブジェクトとしてマップを送信します] 'map'は実際にはプロパティを割り当てるオブジェクトなので、それを直列化するのではなく、

どのように私は正しくそれをシリアル化することができます知っているそれはWCFサービスによって辞書オブジェクトとしてデシリアライズされますか?

+1

[JSON.stringify](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify)機能を試しましたか? '{" a ":1、" b ":2、" c ":3}' – Imperative

+0

wcfはスローしますが、フォーマッタは例外をスローしました。メッセージを非直列化しようとしています – LoghamLogan

答えて

5

デフォルトでは、WCFはJSONオブジェクトとしてDictionaryを表すのではなく、代わりにキーと値のペアの配列として表します。その地図を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/

これはあなたのサービスにそのオブジェクトを渡すの1つの方法を示してJSコード、ajax呼び出しにjQueryを使用):

<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> 
+0

あなたのdictionaryToKVPArray()メソッドは、私がこれに必要なものです!Thanks =)答えとしてマークされているのは、WCFサービスに正しいデータを渡してDictionaryオブジェクトを逆シリアル化する方法と、JavaScriptを再びJavaScriptに戻す方法を示しているからです。 – LoghamLogan

4

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); 

Json.Net frameworkを使用してWCFサービスでそれをデシリアライズ:

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

これは理想的ではありませんが、機能します。

関連する問題