35

更新 問題が見つかりました -- 間違ったクラスから継承していたため、JsonConverter である必要がありました。

System.Data.Entity.Spatial.DbGeography 型の Location プロパティを持つクラスがあります。デフォルトの Json.NET シリアライザーは、次のような JSON テキストを出力します。

  ...
  "PlaceType": 0,
  "Location": {
    "Geography": {
      "CoordinateSystemId": 4326,
      "WellKnownText": "POINT (-88.00000 44.00000)"
    }
  },
  "AddedDT": null,
  ...

次のようなテキストを出力したい:

  ...
  "PlaceType": 0,
  "Location": [-88.00000,44.00000],
  "AddedDT": null,
  ...

...だから私がすべきことは、現在 DbGeography タイプで使用されているコンバーターをオーバーライドすることです。

CustomCreationConverters と ContractResolvers を使用するこれまでに見た例は、そのクラスのプロパティのみである型ではなく、シリアル化されるメイン クラスのシリアライザーを置き換える方法に対処しているようです。internalコードで DbGeography を定義しておらず、コンストラクターがなく、ファクトリ メソッドによってのみインスタンス化できるため、実質的にシール クラスであるため、オーバーライドされているクラスに注釈を付けることを含む例は機能しません。

JsonConverter を型に流暢に適用する方法はありますか? もしそうなら、コンバーターはどのように見えますか? WriteJson() メソッドをオーバーライドするだけですか?

4

3 に答える 3

50

次のように、単一の属性にカスタム シリアライザーを追加できます。

public class Comment
{
    public string Author { get; set; }

    [JsonConverter(typeof(NiceDateConverter))]
    public DateTime Date { get; set; }

    public string Text { get; set; }
}

public class NiceDateConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var date = (DateTime) value;
        var niceLookingDate = date.ToString("MMMM dd, yyyy 'at' H:mm tt");
        writer.WriteValue(niceLookingDate);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

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

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }
}

次に、オブジェクトを JsonConvert.SerializeObject() でシリアル化すると、カスタム シリアライザーが Date プロパティに使用されます。

于 2015-05-06T17:42:06.453 に答える