2013-02-21 33 views
7

Tôi muốn chuyển mảng kết hợp tới dịch vụ wcf json.Chuyển bản đồ javascript tới dịch vụ json wcf

Vì vậy, trong Javascript Tôi có một cái gì đó tương tự như thế này:

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

Và trong dịch vụ WCF của tôi, tôi muốn để mong đợi một từ điển:

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

Nhưng nó sẽ gửi bản đồ như một [đối tượng Object ] thay vì tuần tự hóa nó vì 'bản đồ' thực sự chỉ là một đối tượng mà tôi gán thuộc tính cho.

Có ai biết làm thế nào tôi có thể tuần tự hóa nó một cách chính xác để làm cho nó deserialized như một đối tượng từ điển của dịch vụ WCF?

+1

Bạn đã thử hàm [JSON.stringify] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify) chưa? 'echo JSON.stringify (map);' nên xuất ra một chuỗi: '{" a ": 1," b ": 2," c ": 3}' – Imperative

+0

Nó thực hiện nhưng wcf ném: Trình định dạng đã ném một ngoại lệ trong khi cố gắng để deserialize tin nhắn – LoghamLogan

Trả lời

5

Theo mặc định, WCF không đại diện cho Dictionary làm đối tượng JSON - nó đại diện cho chúng dưới dạng mảng của cặp khóa/giá trị thay thế. Vì vậy, để gửi bản đồ đó tới dịch vụ WCF, bạn cần phải bí mật hóa nó một cách thích hợp (xem mã bên dưới).

Một cách khác là sử dụng trình định dạng tin nhắn tùy chỉnh, cách biết cách nhập từ điển dựa trên các đối tượng JSON. Để biết thêm thông tin về các trình định dạng tin nhắn, hãy kiểm tra số blog post này.

Điều này cho thấy một cách để đi qua đối tượng sử dụng dịch vụ của bạn:

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/Mã JS, sử dụng jQuery cho cuộc gọi 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> 
+0

Từ điển của bạnToKVPArray() phương pháp chỉ là những gì tôi cần thiết cho việc này!Thanks =) Được đánh dấu là câu trả lời vì nó cho thấy chính xác cách truyền dữ liệu chính xác cho dịch vụ WCF để deserialize một đối tượng Dictionary, cũng như đưa nó trở lại vào javascript một lần nữa! – LoghamLogan

4

Tôi đã thực hiện việc này bằng cách sử dụng JSON.stringify(map) để nhận phiên bản bản đồ được sắp xếp theo thứ tự. Sau đó, chuyển nó tới dịch vụ WCF dưới dạng một chuỗi thay vì một từ điển và tự deserializing nó trong phương pháp sử dụng Json.Net framework.

In nhiều bản đồ:

{'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 nó trong các dịch vụ WCF sử dụng Json.Net framework:

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

Nó không lý tưởng, nhưng không hoạt động.

Các vấn đề liên quan