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

動作する前に、次のことを行う必要があります。

  • WebサービスにScriptService属性を設定します
  • ScriptMethodWebサービスに属性を配置します

そうすれば、サーバーでJSONを自分で解析して作成する必要もありません。WSインフラストラクチャがそれを行います。

次に、クライアントサイトでmsg.dを使用するだけです。JSOn文字列から自動的に逆シリアル化されます。

クライアント側で行う必要があることについては、jQueryを使用してASP.NETJSONWebサービスを使用する方法を参照してください。

ここに、クライアント側とサーバー側の完全な動作サンプルがあります

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<string,Tvalue>。ディクショナリは、JSONとしてシリアル化できますが、XMLとしてはシリアル化できません。キータイプtoString()メソッドを使用して、キーを文字列に変換します。intこれは、他の多くのタイプで完全に機能します。このメソッドを拡張して、必要に応じてキーを文字列に変換するデリゲートを受け取ることができます。

クライアント側では、このソリューションと最初の編集のソリューションで同じことが得られます。最初の編集の利点は、XMLへのシリアル化もサポートできることです。.asmxページからメソッドを呼び出し、WebMethodを通常のXMLWebMethodとして使用できます。

編集:.asmx Webサービスの辞書<>のシリアル化:

asmxで使用されるシリアライザーは、XMLの辞書のシリアル化をサポートしていません。カスタムクラスを作成し、辞書をこのカスタムクラスのリストに変換できます。このリストには、キーと値のプロパティがあります(シリアライザーは、シリアル化KeyValuePairまたはをサポートしていないTupleため、独自のクラスを使用する必要があります)。

このクラスには2つの目的があります。

  • これは、asmxforJSONで使用されるシリアライザーでシリアル化できるクラスです。
  • クラスの要素のリストで辞書を変換できます

    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

これはjqueryajax呼び出しです:

  $(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).Valuefunction (index, value)

于 2014-06-05T19:53:17.677 に答える