1

我有将从服务器返回的字典,我将其转换为 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/>");
        });
      }
    });
4

4 回答 4

3

在它起作用之前你必须做这些事情:

  • 为您的网络服务添加一个ScriptService属性
  • 在您的网络服务中添加一个ScriptMethod属性

如果这样做,您甚至不需要自己在服务器中解析创建 JSON。WS 基础架构将为您完成。

然后,只需在客户端站点上使用 msg.d。它将自动从 JSOn 字符串反序列化。

看这里Using jQuery to Consume ASP.NET JSON Web Services你需要在客户端做什么。

在这里,您有一个完整的客户端和服务器端工作示例

请注意,在 ASP.NET 3.5 之前,响应消息会直接带来数据。在 3.5 及更高版本中,数据位于消息的 .d 属性中。

EDIT2:更简单的方法 我在第一次编辑中犯了一个错误:.asmx 无法将 Dictionay 序列化为 XML。因此,当我通过 .asmx 页面在第一次编辑中测试解决方案时,出现了错误。但是 JSON 可以序列化具有字符串或对象作为键的字典。

因此,您可以使用此类将您转换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序列化字典。您可以创建一个自定义类并将您的字典转换为该自定义类的列表,该列表具有一个键和一个值属性(序列化程序不支持序列化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;
        }
    }
    

您的 Web 方法应如下所示:

    [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 必须与你的字典键和值类型相同。

在客户端,您会得到一组具有 Key 和 Value 属性的对象,可以像这样访问:

  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
        }
    });
  });
于 2012-05-03T14:38:16.250 回答
2
$.each(msg.d, function() {
    $("#data2").append(this.Key + " " + this.Value + "<br/>");
});

此外,您的序列化似乎无法正常工作,因为返回的响应并未完全解析为 JSON。的内容不d应该是一个字符串,它应该是一个对象/数组。

于 2012-05-03T14:22:48.517 回答
1

基于上面的 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();
}
于 2012-09-16T11:25:39.757 回答
1

它对我有用的唯一方法是

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)方法。

于 2014-06-05T19:53:17.677 回答