18

私はこのようなPOCOを持っています:

public class BlogEntry
{
    public string Title { get; set; }
    public DateTime Date { get; set; }
}

ほとんどの場合、Entity Framework からハイドレートされていますが、Entity Framework の外部で使用することもできますし、今後も使用する予定です。

EF からの日付の DateTimeKind は指定されていません。これは、私が読んだものから正常です。

この POCO を (ServiceStack Redis クライアントを使用して) Redis にキャッシュすると、Local の DateTimeKind が返されます。

そのため、返されたオブジェクトにはジッターがあります。最初のパス (キャッシュされていない) には、オフセットのない ISO-8601 があります (DateTimeKind.Unspecified)。2 番目のパス (キャッシュ) は、オフセット付きの ISO-8601 です (DateTimeKind.Local を使用した Redis から)。

ServiceStack JSONシリアライザに日付を常に特定のDateTimeKindとして解釈させる方法はありますか? (「JsConfig.AppendUtcOffset」プロパティがあることは知っていますが、それが true であろうと false であろうと、値は決して変化しませんか?)

または、型指定された RedisClient からの逆シリアル化プロセスのどこかで、DateTimeKind をローカルにしますか?

POCO を手動で変更して DateTimeKind を強制することはできますが、それは機能しますが、エラーが発生しにくいものを望んでいました。

4

3 に答える 3

21

@mythzの回答よりも構成可能なものが必要な場合はDateTimeKind、DateTimeとオプションでDateTimeをオーバーライドすることで、DateTimeのシリアル化または逆シリアル化を強制できますか? シリアル化および/または逆シリアル化の方法。

シリアル化されたすべての DateTime を強制的に UTC として解釈する

JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Local).ToString();

DateTime が指定された形式でない場合は、これをさらに一歩進めて、逆シリアル化でエラーを発生させることができます。クライアントにすべてのリクエストでタイムゾーンを強制的に指定させたいときにこれを使い始めましたが、必ずしも常に Utc である必要はありません。

JsConfig<DateTime>.DeSerializeFn = time =>
{
  if (!IsInCorrectDateFormat(time))
    throw new System.Runtime.Serialization.SerializationException(BadDateTime);

  return ServiceStack.Text.Common.DateTimeSerializer.ParseDateTime(time);
};
于 2013-10-31T13:53:02.537 に答える
7

オフセットはDateTimeKind日付と共に格納されないため、デフォルトで ServiceStack シリアライザーは日付がローカルであると想定し、UTC としてシリアル化され、ローカルとして逆シリアル化されます。

DateTimeKind.Unspecified次の方法で UTC と見なすことができます。

JsConfig.AssumeUtc = true;
于 2013-10-31T01:32:07.467 に答える
6

bpruitt-goddard ソリューションの微調整。すべての功績は彼にあります。

JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Local).ToString("o");
        JsConfig<DateTime?>.SerializeFn = 
            time => time != null ? new DateTime(time.Value.Ticks, DateTimeKind.Local).ToString("o") : null;
        JsConfig.DateHandler = DateHandler.ISO8601;

そのため、サービス スタックから送信される日付は ISO8601 日付形式に強制され、受信する日付は ISO8601 文字列から C# 日付に自動的に変換されます。

于 2015-06-04T16:20:10.940 に答える