簡體   English   中英

如何使用json-ajax解析Dictionary類型

[英]How to parse Dictionary type with json-ajax

我有將從服務器返回的字典,我將其轉換為json字符串格式,如下所示:

public static class Extensions 
{ 
    public static string ToJson<T>(this T obj) 
    { 
        MemoryStream stream = new MemoryStream(); 
        try { 
            DataContractJsonSerializer jsSerializer = new DataContractJsonSerializer(typeof(T)); 
            jsSerializer.WriteObject(stream, obj); 

            return Encoding.UTF8.GetString(stream.ToArray()); 
        } 
        finally 
        { 
            stream.Close(); 
            stream.Dispose();
        } 
    } 
    public static T FromJson<T>(this string input) 
    { 
        MemoryStream stream = new MemoryStream();
        try {
            DataContractJsonSerializer jsSerializer = new DataContractJsonSerializer(typeof(T));
            stream = new MemoryStream(Encoding.UTF8.GetBytes(input)); 
            T obj = (T)jsSerializer.ReadObject(stream); return obj; 
        } 
        finally 
        { 
            stream.Close(); 
            stream.Dispose();
        }
    } 
}

[WebMethod]
public string callme()
{
    Dictionary<int, string> myObjects = new Dictionary<int, string>();
    myObjects.Add(1, "This");
    myObjects.Add(2, "is");
    myObjects.Add(3, "cool");
    string json = myObjects.ToJson();
    return json;
}

所以結果是:

{"d":"[{\"Key\":1,\"Value\":\"This\"},{\"Key\":2,\"Value\":\"is\"},{\"Key\":3,\"Value\":\"cool\"}]"}

我如何解析在jQuery? 我正在嘗試但沒有幫助

$.ajax({
      type: "POST",
      url: "web.asmx/callme",
      data: "{}",
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      success: function(msg){
          $.each(msg.d, function (i) {
          $("#data2").append(i.Key + " " + i.Value + "<br/>");
        });
      }
    });

您必須先完成以下操作:

  • ScriptService屬性添加到您的Web服務
  • ScriptMethod屬性放在您的Web服務中

如果這樣做,您甚至不需要自己解析在服務器中創建JSON。 WS基礎結構將為您完成此任務。

然后,只需在客戶端站點上使用msg.d。 它將從JSOn字符串自動反序列化。

在此處查看使用jQuery消費ASP.NET JSON Web服務,以了解您需要在客戶端執行的操作。

在這里,您將獲得客戶端和服務器端的完整工作示例

請注意,在ASP.NET 3.5之前,響應消息直接帶來了數據。 在3.5及更高版本中,數據位於消息的.d屬性中。

EDIT2:更簡單的方法在第一次編輯中我犯了一個錯誤:.asmx無法將Dictionay序列化為XML。 因此,當我通過.asmx頁面在第一次編輯中測試解決方案時,出現錯誤。 但是JSON可以序列化具有字符串或對象作為鍵的Dictionary。

因此,您可以使用此類使用以下通用類將Dictionary<int,string>轉換為Dictionary<string,string>

    public class DictionaryConverter
    {
        public static Dictionary<string,TValue> 
            ConvertDictionary<TKey,TValue>(Dictionary<TKey,TValue> dict)
        {
            Dictionary<string,TValue> newDict
                = new Dictionary<string, TValue>();
            foreach(TKey key in dict.Keys)
            {
                newDict.Add(key.ToString(), dict[key]);
            }
            return newDict;
        }
    }

此類可以將具有任何鍵類型的任何Dictionary轉換為Dictionary<string,Tvalue>字典,該字典可以序列化為JSON,但不能序列化為XML。 它使用鍵類型toString()方法將鍵轉換為字符串。 這將非常適合int和許多其他類型。 可以擴展此方法以接收委托,以便在必要時將密鑰轉換為字符串。

在客戶端,您可以通過此解決方案獲得相同的結果,並且第一個文件可以編輯。 第一次編輯時的優點是它還可以支持序列化到XML:您可以通過.asmx頁面調用該方法,並將WebMethod用作常規XML WebMethod。

編輯:在.asmx Web服務中序列化Dictionary <>:

與asmx一起使用的序列化器不支持XML的序列化字典。 您可以創建一個自定義類,並將字典轉換為該自定義類的列表,該自定義類具有鍵和value屬性(序列化程序也不支持序列化KeyValuePairTuple ,因此您必須使用自己的類)。

此類有兩個目的:

  • 該類可以使用asmx用於JSON的序列化器進行序列化
  • 允許在類的元素列表中轉換字典

     public class KeyValue<TKey, TValue> { public KeyValue() { } public TKey Key { get; set; } public TValue Value { get; set; } public static List<KeyValue<TKey,TValue>> ConvertDictionary (Dictionary<TKey,TValue> dictionary) { List<KeyValue<TKey, TValue>> newList = new List<KeyValue<TKey, TValue>>(); foreach (TKey key in dictionary.Keys) { newList.Add(new KeyValue<TKey, TValue> { Key = key, Value = dictionary[key] }); } return newList; } } 

您的網絡方法應如下所示:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] // it's JSON by default
    public List<KeyValue<int,string>> GetKeyValueList()
    {
        List<KeyValue<int, string>> list
            = KeyValue<int,string>.ConvertDictionary(yourDictionary);
        return list;
    }

筆記:

  • 您可以使用任何方法名稱代替GetKeyValueList
  • TKey,TValue必須與字典鍵和值的類型相同。

在客戶端,您將獲得具有鍵和值屬性的對象數組,可以像這樣訪問:

  msg.d[0].Key
  msg.d[0].Value

這是jquery ajax調用:

  $(document).ready(function () {
    $.ajax({
        url: 'MyService.asmx/GetKeyValueList',
        type: "POST",
        data: "{}",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: function (msg) {
            // use msg.d array of objects with Key and Value
        }
    });
  });
$.each(msg.d, function() {
    $("#data2").append(this.Key + " " + this.Value + "<br/>");
});

另外,您的序列化似乎無法正常工作,因為返回的響應並未完全解析為JSON。 d的內容不應為字符串,而應為對象/數組。

基於上面的JotaBe回答,我創建了這個擴展方法:

    public class KeyValue<TKey, TValue>
    {
        public TKey Key { get; set; }
        public TValue Value { get; set; }

        public KeyValue()
        {
        }       
    }
    public static class KeyValue_extensionMethods
    {
        public static List<KeyValue<TKey, TValue>> ConvertDictionary<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
        {
            var  keyValueList = new List<KeyValue<TKey, TValue>>();
            foreach (TKey key in dictionary.Keys)
                keyValueList.Add(new KeyValue<TKey, TValue> { Key = key, Value = dictionary[key] });
            return keyValueList;
        }
    }

然后,我可以使用{object} .ConvertDictionary()語法來使用它。 例如:

[WebMethod(EnableSession = true)] [Admin(SecurityAction.Demand)]       
public List<KeyValue<Guid, string>>     Data_GuidanceItems_FileMappings()        
{
    return TM_Xml_Database.GuidanceItems_FileMappings.ConvertDictionary();
}

它對我有用的唯一方法是

var $nomeP = $("#<%= tbxBuscaJornalista.ClientID %>").val();

             $.ajax({
             url: "MyPage.asmx/MyMethod",
             dataType: "json",
             type: "POST",
             data: "{ 'variableName': '"+$nomeP+"' }",
             contentType: "application/json; charset=utf-8",
             success: function (msg) {
                 $.each(msg.d, function (index, value) {
                     $("#somePanel").append(index + " " + value + "<br/>");
                 });
             },
             error: function (XMLHttpRequest, textStatus, errorThrown) {
                 alert("Error: " + errorThrown + " XmlRequest: " + XMLHttpRequest);
             }
         });

請注意以下行data: "{ 'variableName': '"+$nomeP+"' }" ,它顯示我必須將變量名(與后面的代碼相同) 和值括在單引號中 否則它將無法正常工作。 另外,我嘗試迭代並使用$(this).Key$(this).Value但這也不起作用。 我被迫使用function (index, value)方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM