6

現在、次のようなクラスがあります。

public class TestSerilizer
{
    public int IntValue;
    public DateTime DTValue;
}

そして、JSONにシリアル化されたクラスを返すコントローラーは次のようになります。

public ActionResult TestJson()
{
    TestSerilizer testDT = new TestSerilizer();
    return Json(testDT);
}

これにより、JSONのよう/Date(123456)/に見える日付が生成されることはよく知られていますが、これは望ましいとは言えません。私の目的のために、自分の見解に合った方法で日付をフォーマットする属性を追加できるようにしたいと思います。理想的には、ビューモデルを次のように変更したいと思います。

public class TestSerilizer
{
    public int IntValue;
    [JSONDateFormatter("hh:mm tt")]
    public DateTime DTValue;
}

これにより、フォーマットされた日付のJSONデータが生成されます。JSONシリアル化を乗っ取ってそのようなことをする方法はありますか?これは、この暗黙的なJSONシリアル化とJavaScriptSerializerクラスの明示的な使用の両方を備えた大規模なコードベースであるため、両方の状況で機能するメソッドをお勧めしますが、それが不可能な場合があることを理解しています。

4

2 に答える 2

7

これは通常、オブジェクトの日付のシリアル化を管理する方法です。バイナリとjsonの両方でシリアル化できる必要があるため、これはdataMemberプロパティを使用することに注意してください。

[DataContract]
[Serializable]
public class YourClass
{
        [DataMember]
        private long timeStampLong;


        [IgnoreDataMember]
        public DateTime TimeStamp
        {
            get { return new DateTime(timeStampLong); }
            set { timeStampLong = value.Ticks; }
        }
}

これにより、日時がjsonで読み取り可能にならない場合がありますが、一貫性が保たれます。異なるjsonライブラリは、日時のシリアル化を異なる方法で処理するため、それらすべてに同じ方法でシリアル化を強制できるようにする必要があります。

編集:これはC#プロパティの意味での2番目のプロパティではなく、プロパティの基になるフィールドにすぎないことに注意してください。代わりに、基になるフィールドを文字列にすることができ、その基になるフィールドがオブジェクトの外部に公開されることはありません。あなたのおかげで、IgnoreDataMemberあなたはまだ単一の値だけをシリアル化しています。

Edit2:誰かがこれを実装する必要がある場合のより完全な答えのためのクラス宣言を追加しました。

編集:より完全な例として、私が使用した他のオプションを含めると思いました(バッキングフィールドとして文字列を使用)

    /// <summary>
    /// Representations of the TimeStamp used for serialization
    /// </summary>
    [DataMember(Name = "TimeStamp")]
    private String timeStamp;

    /// <summary>
    /// timestamp when the request is sent
    /// </summary>
    [IgnoreDataMember]
    public DateTime TimeStamp
    {
        get { return DateTime.Parse(timeStamp, null, DateTimeStyles.RoundtripKind); }
        set { timeStamp = value.ToUniversalTime().ToString("o"); }
    }
于 2013-02-28T16:28:54.657 に答える
0

@jzworkmanが指摘したように、その応答の手法の概要は、内部のDateTime値がシリアル化される方法を制御する方法です。私は常に文字列ベースの形式を使用することに固執します。これは、他のほとんどのものによって確実に解析できます。可能であれば、タイムゾーンマッピングを適切に処理できるISO8601形式を使用することに固執します。C#では、myDateTimeValue.ToString( "o")を使用して、ISO8601のDateTimeの文字列を取得できます。

ISO8601に関するウィキペディアの記事

于 2013-02-28T17:14:40.187 に答える