web-dev-qa-db-ja.com

Json.Netでシリアル化するときにカスタムDateTime形式を指定する

ASP.NET Web APIを使用してデータを公開するAPIを開発しています。

APIの1つで、クライアントはyyyy-MM-dd形式で日付を公開することを望んでいます。このクライアントに非常に固有であるため、グローバル設定(GlobalConfiguration.Configuration.Formatters.JsonFormatterなど)を変更したくありません。そして、私はそれを複数のクライアント向けのソリューションで開発しています。

私が考えることができる解決策の1つは、カスタムJsonConverterを作成し、それをプロパティに入れて、カスタムフォーマットを行う必要があることです

例えば.

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}

他の簡単な方法があるのではないかと考えているだけです。

98
Stay Foolish

あなたは正しい軌道に乗っています。グローバル設定を変更できないと言ったので、次にお勧めするのは、必要に応じてJsonConverter属性を適用することです。 Json.Netには既に IsoDateTimeConverter が組み込まれているため、日付形式を指定できます。残念ながら、属性の唯一の引数は型であるため、JsonConverter属性を介して形式を設定することはできません。ただし、単純な解決策があります。IsoDateTimeConverterをサブクラス化し、サブクラスのコンストラクターで日付形式を指定します。必要に応じてJsonConverter属性を適用し、カスタムコンバーターを指定すれば準備完了です。必要なコード全体は次のとおりです。

class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-dd";
    }
}

そこに時間があることを気にしないのであれば、IsoDateTimeConverterをサブクラス化する必要さえありません。デフォルトの日付形式はyyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFKです( ソースコード を参照)。

126
Brian Rogers

次のアプローチを使用できます。

public class DateFormatConverter : IsoDateTimeConverter
{
    public DateFormatConverter(string format)
    {
        DateTimeFormat = format;
    }
}

そして、このように使用します:

class ReturnObjectA 
{
    [JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
    public DateTime ReturnDate { get;set;}
}

DateTimeFormat文字列は、ここで説明されている.NET形式文字列の構文を使用します。 https://docs.Microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

65
Keith Hill

グローバルな書式設定を変更せずに、IsoDateTimeConverterインスタンスを使用して行うこともできます。

string json = JsonConvert.SerializeObject(yourObject,
    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });

これは、JsonConvert.SerializeObject引数をとるparams JsonConverter[]オーバーロードを使用します。

42
Saeb Amini

シリアライザー設定のオーバーロードのいずれかを使用しても利用可能です:

var json = JsonConvert.SerializeObject(someObject, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

または

var json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

タイプを取るオーバーロードも利用できます。

12
Matt

ヘルパークラスをビルドしてプロパティ属性に適用

ヘルパークラス:

public class ESDateTimeConverter : IsoDateTimeConverter
{
    public ESDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
    }
}

あなたのコードは次のように使用します:

[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }
4
Xin

Json convert属性の装飾が機能しない場合があります。例外として、「2010-10-01」は有効な日付。このタイプを回避するには、プロパティのjson convert属性を削除し、以下のようにdeserilizedObjectメソッドで言及しました。

var addresss = JsonConvert.DeserializeObject<AddressHistory>(address, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" });
0
Muni Chittem

私が使用している別のソリューションがあります。文字列プロパティを作成し、jsonに使用するだけです。このプロパティは、適切な形式の日付を返します。

class JSonModel {
    ...

    [JsonProperty("date")]
    public string MyDate { get; set; }

    public string CustomDate {
        get { return MyDate.ToString("DDMMYY"); }
        set { MyDate = DateTime.Parse(value); }
    }

    ...
}

この方法では、追加のクラスを作成する必要はありません。また、異なるデータ形式を作成できます。たとえば、同じDateTimeを使用してHourの別のプロパティを簡単に作成できます。

0
anrodse