2016-11-18 14 views
1

JsonConverterを使用して、配列からオブジェクトにプロパティの型を変更したいとします。たとえば、私はこのようなプロパティを持っています[{"Name":"aaa"}]。シリアル化した後、私はこのような結果を持っています{"__po":"Add",Objects:[{"Name":"aaa"}]}配列をJsonConverterのオブジェクトに変換する方法

は、だから、私は、シリアライザをカスタマイズするためのクラスを作成しました: public enum WriteState { Error = 0, Closed = 1, Object = 2, Array = 3, Constructor = 4, Property = 5, Start = 6 }

public class Serializer : ISerializer 
{ 
    public JsonSerializerSettings SerializerSettings { get; set; } 

    public Serializer() 
    { 
     SerializerSettings = new JsonSerializerSettings(); 
     SerializerSettings.Converters.Add(new ParseArrayToObjectJsonConverter()); 
    } 

    public class ParseArrayToObjectJsonConverter : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      if (objectType.GetTypeInfo().Name.EndsWith("Array")) 
      { 
       return true; 
      } 
      return false; 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 

     } 
    } 
} 

私はJsonWriterはこのような列挙型を返すことができ、このプロパティpublic WriteState WriteState { get; }を持っていることがわかります。

私のWriteJsonメソッドでは、のタイプはWriteState.Arrayですが、オブジェクトを返すためにWriteStateという値を設定できないという問題があります。この問題を処理するための他の解決策はありますか?

+0

JsonWriterがこのプロパティを持っています。public WriteState WriteState {get; }誰がこの「パブリック列挙WriteStateような列挙を返すことができ { エラー= 0、 クローズ= 1、 オブジェクト= 2、 アレイ= 3、 コンストラクタ= 4、 施設= 5、 スタート= 6 } '私の場合、Writer.WriteStateの値はWriteState.Arrayですが、オブジェクトを返すためにWriter.WriteStateの値を設定できないという問題があります。 –

答えて

1

JsonWriterJsonConverterの範囲で使用する方法を誤解していると思います。あなたは作家のWriteStateを混乱させる必要はありません。これは、ライターが現在書いていることを示す読み取り専用のプロパティです。直接変更することはできません。代わりに、作者のWriteXxx()メソッドを使用して、実際に必要なJSONを書き出す必要があります。ここでは、オブジェクトの配列をラップJsonConverterを実装する方法を次のとおりです。ここで

public class WrapArrayInObjectJsonConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     // This will cause the converter to wrap ALL IEnumerables (except strings) in an object. 
     return typeof(IEnumerable).IsAssignableFrom(objectType) && objectType != typeof(string); 

     // If you only want to this converter to wrap specific kinds of arrays, change this 
     // method accordingly. For example, this will only wrap Foo[] or List<Foo>: 
     //return typeof(IEnumerable<Foo>).IsAssignableFrom(objectType); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     IEnumerable array = (IEnumerable)value; 
     writer.WriteStartObject(); 
     writer.WritePropertyName("__po"); 
     writer.WriteValue("Add"); 
     writer.WritePropertyName("Objects"); 
     writer.WriteStartArray(); 
     foreach (object item in array) 
     { 
      serializer.Serialize(writer, item); 
     } 
     writer.WriteEndArray(); 
     writer.WriteEndObject(); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

は、コンバータを使用する例です:

Foo[] array = new Foo[] 
{ 
    new Foo { Name = "aaa" }, 
    new Foo { Name = "bbb" } 
}; 

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.Converters.Add(new WrapArrayInObjectJsonConverter()); 

string json = JsonConvert.SerializeObject(array, settings); 
Console.WriteLine(json); 

出力:

{"__po":"Add","Objects":[{"Name":"aaa"},{"Name":"bbb"}]} 

フィドル: https://dotnetfiddle.net/79mXF2

+0

これはまさに私が必要とするものです。 –

関連する問題