2013-04-18 31 views
8

私はJsonConverterを書いています。特に、私は既存のシリアライゼーションの振る舞いを取って、読み込み時にこれらの追加プロパティを書き込み/読み込みする際のいくつかの追加プロパティについて説明します。JsonConverterでJsonSerializerを再帰的に呼び出します。

JsonConverterの中で、大文字の変換機能を実行するには、渡されたJsonSerializerインスタンスを使用したいと思います。しかし、私はこれを行うと、シリアライザが変換器などを呼び出すシリアライザを呼び出すコンバータに呼び出す再帰的なループに終わります。

私は人々が使用するのを見たことがありますJsonConvert.SerializeObject、シリアライザインスタンスからすべてのコンバータを渡し、thisを除く。しかし、それはカスタム契約リゾルバとDateTimeハンドリングのような私のシリアライザで行った他のすべてのカスタマイズをバイパスするので、私のためにはうまくいかないでしょう。

は、私はどちらかのことができる方法はあります:

  1. は、手動で新しいものを構築することなく、私に渡されたシリアライザを(私に渡されたシリアライザのインス​​タンスを使用しますが、何とか私のコンバータを除外、または
  2. クローンとプロパティでプロパティをコピー)、コンバータを削除しますか?

答えて

0

これは非常に一般的な問題です。 "JsonConvert.SerializeObject"を使用することは悪い考えではありません。しかし、いくつかの状況(通常はコレクション)で使用できる1つのトリックは、読み込み時に単純な導関数に書き込んだりデシリアライズするときにインターフェイスにキャストすることです。

以下

KVPsのセットとしてではなく、(:)ここでは私の年齢を示す)オブジェクトのように見える連載されている可能性があります辞書を扱う簡単なコンバータです

注「WriteJsonは、」IDictionaryを< Kへのキャスト、V>と "ReadJson"は "DummyDictionary"を使用します。あなたは正しいことに終わりますが、再帰を起こさずに渡されたシリアライザを使います。

/// <summary> 
/// Converts a <see cref="KeyValuePair{TKey,TValue}"/> to and from JSON. 
/// </summary> 
public class DictionaryAsKVPConverter<TKey, TValue> : JsonConverter 
{ 
    /// <summary> 
    /// Determines whether this instance can convert the specified object type. 
    /// </summary> 
    /// <param name="objectType">Type of the object.</param> 
    /// <returns> 
    ///  <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>. 
    /// </returns> 
    public override bool CanConvert(Type objectType) 
    { 
     if (!objectType.IsValueType && objectType.IsGenericType) 
      return (objectType.GetGenericTypeDefinition() == typeof(Dictionary<,>)); 

     return false; 
    } 

    /// <summary> 
    /// Writes the JSON representation of the object. 
    /// </summary> 
    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param> 
    /// <param name="value">The value.</param> 
    /// <param name="serializer">The calling serializer.</param> 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var dictionary = value as IDictionary<TKey, TValue>; 
     serializer.Serialize(writer, dictionary); 
    } 

    /// <summary> 
    /// Reads the JSON representation of the object. 
    /// </summary> 
    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param> 
    /// <param name="objectType">Type of the object.</param> 
    /// <param name="existingValue">The existing value of object being read.</param> 
    /// <param name="serializer">The calling serializer.</param> 
    /// <returns>The object value.</returns> 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     Dictionary<TKey, TValue> dictionary; 

     if (reader.TokenType == JsonToken.StartArray) 
     { 
      dictionary = new Dictionary<TKey, TValue>(); 
      reader.Read(); 
      while (reader.TokenType == JsonToken.StartObject) 
      { 
       var kvp = serializer.Deserialize<KeyValuePair<TKey, TValue>>(reader); 
       dictionary[kvp.Key] = kvp.Value; 
       reader.Read(); 
      } 
     } 
     else if (reader.TokenType == JsonToken.StartObject) 
      // Use DummyDictionary to fool JsonSerializer into not using this converter recursively 
      dictionary = serializer.Deserialize<DummyDictionary>(reader); 
     else 
      dictionary = new Dictionary<TKey, TValue>(); 

     return dictionary; 
    } 

    /// <summary> 
    /// Dummy to fool JsonSerializer into not using this converter recursively 
    /// </summary> 
    private class DummyDictionary : Dictionary<TKey, TValue> { } 
} 
-3

申し訳ありませんが、多分私は混乱しています。私は自分のオブジェクトをシリアル化のためにこの方法を使用:

using System; 
 
using Newtonsoft.Json; 
 

 
namespace Utilities 
 
{ 
 
    public static class serializer 
 
    { 
 
     public static string SerializeObject(object objectModel) { 
 
      return JsonConvert.SerializeObject(objectModel); 
 
     } 
 
     public static object DeserializeObject<T>(string jsonObject) 
 
     { 
 
      try 
 
      { 
 
       return JsonConvert.DeserializeObject<T>(jsonObject); 
 
      } 
 
      catch (Exception ex) { return null; } 
 
      
 
     } 
 
    } 
 
}

を、私はこのコードを使用:

userLoged = (modelUser)serializer.DeserializeObject<modelUser>((string)Session["userLoged"]);

私はこれが参考にされている願っています。

+1

これは質問された質問には答えません。問題は「JsonConvertを使用してオブジェクトをシリアル化するにはどうすればよいのですか?カスタムJsonConverter内部からの再帰的ループを避ける方法を尋ねていました。 ['JsonConvert'](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConvert.htm)と[' JsonConverter'](http://www.newtonsoft.com/json/help/html /T_Newtonsoft_Json_JsonConverter.htm)は、Json.Netの2つの全く異なるクラスです。 –

関連する問題