web-dev-qa-db-ja.com

Json.NETを使用したカスタムデシリアライゼーション

クラスがあります

public class Order
{
   public int Id { get; set; }
   public string ShippingMethod { get; set; }
}

そして、以下のJSONデータを上記のクラス/オブジェクトにデシリアライズしたい

string json = @"{
  'Id': 1,
  'ShippingMethod': {
     'Code': 'external_DHLExpressWorldwide',
     'Description': 'DHL ILS Express Worldwide'
  }
}";

私の考えは、JSONのShippingMethodはオブジェクトですが、ただShippingMethod.Code(JSONで)ShippingMethodにデシリアライズ中にstringクラスのOrderとして渡されます。

Json.NET を使用してその目標を達成するにはどうすればよいですか?

CustomJsonConverter を使用して達成できると思います。しかし、私は混乱します。ドキュメントの例は、WriteJsonのみであり、ReadJsonではありません。

13
Habibillah

上記の質問で述べたように、 JsonConverter を使用して問題を解決します。私の完全なコードの下:

public class Order
{
    public int Id { get; set; }

    [JsonConverter(typeof(ShippingMethodConverter))]
    public string ShippingMethod { get; set; }
}

public class ShippingMethodConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException("Not implemented yet");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return string.Empty;
        } 
        else if (reader.TokenType == JsonToken.String)
        {
            return serializer.Deserialize(reader, objectType);
        }
        else
        {
            JObject obj = JObject.Load(reader);
            if (obj["Code"] != null) 
                return obj["Code"].ToString();
            else 
                return serializer.Deserialize(reader, objectType);
        }
    }

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

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}
25
Habibillah
 dynamic o = JsonConvert.DeserializeObject(json);
 var order = new Order
 {
     Id = o.Id,
     ShippingMethod = o.ShippingMethod.Code
 };

オブジェクトを動的として逆シリアル化し、動的オブジェクトのプロパティにアクセスしてOrderオブジェクトを埋めます

8
Tinwor

JsonPropertyおよびJsonIgnore属性を使用して、逆シリアル化プロセスを指示できます。したがって、モデルは次のようになります。

public class Order
{
    public int Id { get; set; }

    [JsonIgnore]
    public string ShippingMethod
    {
        get
        {
            return (string)TempShippingMethod?["Code"];
        }
    }

    [JsonProperty("ShippingMethod")]
    private JObject TempShippingMethod { set; get; }
}

var res = JsonConvert.DeserializeObject<Order>(json);
7
L.B