web-dev-qa-db-ja.com

{key:key、value:value、...}ではなく{key:value、...}への辞書のC#JSONシリアル化

DataContractJsonSerializerという形式の.Net Dictionary <Key、Value>をJSONにシリアル化することは可能ですか?

{
  key0:value0,
  key1:value1,
  ...
}

入力の定義済み構造がないため、辞書<K、V>を使用します。

DataContractJsonSerializer resultだけがおもしろい!既に「サロゲート」の例を見つけましたが、出力に追加の「データ」があり、辞書<K、String>がある場合、エスケープもfalseです。


私は解決策を見つけました、何が必要ですか!まず、シリアライズ可能な「辞書」クラス:(もちろん、このサンプルは1つの方法で機能しますが、デシリアライズは必要ありません)

[Serializable]
public class MyJsonDictionary<K, V> : ISerializable {
    Dictionary<K, V> dict = new Dictionary<K, V>();

    public MyJsonDictionary() { }

    protected MyJsonDictionary( SerializationInfo info, StreamingContext context ) {
        throw new NotImplementedException();
    }

    public void GetObjectData( SerializationInfo info, StreamingContext context ) {
        foreach( K key in dict.Keys ) {
            info.AddValue( key.ToString(), dict[ key ] );
        }
    }

    public void Add( K key, V value ) {
        dict.Add( key, value );
    }

    public V this[ K index ] {
        set { dict[ index ] = value; }
        get { return dict[ index ]; }
    }
}

使用法:

public class MainClass {
    public static String Serialize( Object data ) {
        var serializer = new DataContractJsonSerializer( data.GetType() );
        var ms = new MemoryStream();
        serializer.WriteObject( ms, data );

        return Encoding.UTF8.GetString( ms.ToArray() );
    }

    public static void Main() {
        MyJsonDictionary<String, Object> result = new MyJsonDictionary<String, Object>();
        result["foo"] = "bar";
        result["Name"] = "John Doe";
        result["Age"] = 32;
        MyJsonDictionary<String, Object> address = new MyJsonDictionary<String, Object>();
        result["Address"] = address;
        address["Street"] = "30 Rockefeller Plaza";
        address["City"] = "New York City";
        address["State"] = "NY";

        Console.WriteLine( Serialize( result ) );

        Console.ReadLine();
    }
}

そして結果:

{
      "foo":"bar",
      "Name":"John Doe",
      "Age":32,
      "Address":{
         "__type":"MyJsonDictionaryOfstringanyType:#Json_Dictionary_Test",
         "Street":"30 Rockefeller Plaza",
         "City":"New York City",
         "State":"NY"
      }
   }
59
Aaaaaaaa

Json.NETはこれを行います...

Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("key1", "value1");
values.Add("key2", "value2");

string json = JsonConvert.SerializeObject(values);
// {
//   "key1": "value1",
//   "key2": "value2"
// }

その他の例:Json.NETでコレクションをシリアル化する

54

UseSimpleDictionaryFormatでプロパティDataContractJsonSerializerを使用し、trueに設定します。

仕事をします:)

13
Maziar Taheri

このコードでMVC4をそのまま使用しています(ToDictionary内の2つのパラメーターに注意してください)

 var result = new JsonResult()
 {
     Data = new
     {
         partials = GetPartials(data.Partials).ToDictionary(x => x.Key, y=> y.Value)
     }
 };

期待どおりのものが得られます。

{"partials":{"cartSummary":"\u003cb\u003eCART SUMMARY\u003c/b\u003e"}}

重要:MVC4のWebAPIはすぐにJSON.NETシリアル化を使用しますが、標準のJsonResultアクションの結果は使用しません。したがって、カスタムActionResultを使用してJSON.NETシリアル化を強制することをお勧めします。素敵なフォーマットを取得することもできます

簡単なactionresult JsonNetResultがあります

http://james.newtonking.com/archive/2008/10/16/asp-net-mvc-and-json-net.aspx

日付をシリアル化するときに違いがわかります(そして、正しいものを使用していることを確認できます)。

マイクロソフトの方法:

 {"wireTime":"\/Date(1355627201572)\/"}

JSON.NETの方法:

 {"wireTime":"2012-12-15T19:07:03.5247384-08:00"}
4
Simon_Weaver

残念ながら、これはDataContractJsonSerializerの最新バージョンでは現在不可能です。参照: http://connect.Microsoft.com/VisualStudio/feedback/details/558686/datacontractjsonserializer-should-serialize-dictionary-k-v-as-a-json-associative-array

現在推奨されている回避策は、Markが上記で提案したようにJavaScriptSerializerを使用することです。

幸運を!

2
Justin Fyles

MyJsonDictionaryクラスは、結果の出力がXMLエンコードされていることを除いて、私にとってはうまく機能しました。したがって、「0」は"00"になります。私は現在、他の多くと同様に.NET 3.5で立ち往生しているため、他のソリューションの多くは利用できません。 「写真をひっくり返して」逆さまにして、私がマイクロソフトに私が望んでいたフォーマットを与えるように説得することは決してできないことに気づいたが...

string json = XmlConvert.DecodeName(xmlencodedJson);

TADA!

結果は、通常の人間が読み取れる非XMLエンコードの結果です。 .NET 3.5で動作します。

0
Mark Z. Kumler