2012-05-03 9 views
0

私は、私は以下のようにそれJSON文字列フォーマット変換サーバから返される辞書があります。JSON-AJAX

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でそれを解析しますか?私はこれをしようとしてm個が、戻ってくる応答は完全にJSONに解析されないよう

$.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/>"); 
     }); 
     } 
    }); 

答えて

3

あなたはそれが機能する前にこのことを行う必要があるでしょう:

  • は、あなたが行う場合は、Webサービス
  • ScriptService属性は、Webサービスに

ScriptMethod属性を入れて置きますだから、自分でJSONをパースする必要はありません。 WSインフラストラクチャはあなたのためにそれを行います。

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

クライアント側で何をする必要があるかについてはUsing jQuery to Consume ASP.NET JSON Web Servicesこちらをご覧ください。

Here you have a full working sample with client and server side

ASP.NET 3.5より前に、応答メッセージがデータを直接取得したことに注意してください。 3.5以降では、データはメッセージの.dプロパティにあります。

EDIT2:それを を行うための簡単な方法私は第一編集中にミスをした:.asmxファイルはXMLとしてDictionayをシリアル化することはできません。ですから、最初の編集で.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; 
     } 
    } 

JSONとしてシリアル化することができDictionary<string,Tvalue>辞書に任意のキータイプのいずれかの辞書を変換することができます。このクラス、 XMLとしてではありません。文字列のキーを変換するには、キータイプtoString()メソッドを使用します。これはintと他の多くのタイプで完全に動作します。このメソッドは、必要に応じてキーを文字列に変換するデリゲートを受け取るように拡張できます。

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

EDIT:辞書<をシリアル化>の.asmx Webサービスで:

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

このクラスには2つの目的機能:それは

  • がクラスの要素のリストに辞書を変換することができますJSON

  • ためASMXが使用するシリアライザでシリアル化できるクラスだ

    • 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
    • の処理鍵を任意のメソッド名を使用することができ、TValueはあなたの辞書のキーと値のと同じタイプでなければなりません。あなたはこのようaccesedことができるキーと値のプロパティを持つオブジェクトの配列を、取得したクライアント側で

    は:

    $(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 
         } 
        }); 
        }); 
    
    +0

    その後、クライアントサイトで単にmsg.dを使用します。 JSOn文字列から自動的に逆シリアル化されます。私のjsonではどうですか? –

    +0

    "full working sample"のサンプルを見てください。辞書のWebメソッドから返されたデータを変更すると、レスポンスの '.d'プロパティをデシリアライズせずにクライアント側で直接使用できることがわかります。 – JotaBe

    +0

    hmm素敵なありがとう、私の質問は、2つの部分は、ソリューションの上で、あなたとエリーから来ています;) –

    2
    $.each(msg.d, function() { 
        $("#data2").append(this.Key + " " + this.Value + "<br/>"); 
    }); 
    

    はまた、あなたのシリアル化が正しく動作していないと思わざるを得ません。 dの内容は文字列であってはなりません。オブジェクト/配列でなければなりません。

    +0

    'console.log(msg)'を実行してその応答をここに入れることができますか? – Eli

    +0

    。最後の1つ:Object {d = "[{" Key ":1、" Value ":" This ... Key ":3、" Value ":" cool "}]"} –

    +0

    ログ(msgのタイプ。d); ' – Eli

    1

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

    これはjqueryのAJAX呼び出しです上記の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(); 
    } 
    
    1

    唯一の方法は、(コードビハインドで期待どおりに同じ)私は、変数名を囲むに持っていた示したラインdata: "{ 'variableName': '"+$nomeP+"' }"を注意してください

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

    ました単一引用符で囲まれたの値はです。それ以外の場合は動作しません。また、私は反復し、$(this).Key$(this).Valueを使用しようとしましたが、どちらもうまくいかないでしょう。私はfunction (index, value)のアプローチを余儀なくされました。