为什么DateTime.MinValue不UTC时区提前进行序列化? [英] Why can DateTime.MinValue not be serialized in timezones ahead of UTC?
问题描述
我遇到一个WCF REST服务问题。该线对象,我尝试返回具有一定的属性没有设置,导致DateTime.MinValue为DateTime类型的属性。该服务将返回一个空文件(与HTTP状态200 ???)。当我尝试调用JSON序列化自己,即抛出的异常是:
SerializationException:DateTime值是比DateTime.MaxValue或更大比DateTime.MinValue当转换为UTC较小不能被序列化到JSON。
块引用>
这可以通过在控制台中运行以下代码复制应用程序:
DataContractJsonSerializer SER =新DataContractJsonSerializer(typeof运算(DATETIME));
MemoryStream的M =新的MemoryStream();
DateTime的DT = DateTime.MinValue;
//抛出SerializationException在我的时区
ser.WriteObject(男,DT);
串JSON = Encoding.ASCII.GetString(m.GetBuffer());
Console.WriteLine(JSON);
为什么这种行为?我认为这是关系到我的时区(GMT + 1)。由于DateTime.MinValue是默认值(日期时间),我希望这能没有问题被序列化。
如何让我的REST服务的行为有什么建议?我不想改变我的DataContract。
解决方案主要的问题是
DateTime.MinValue
的DateTimeKind.Unspecified
的那种。它被定义为:
<预类=郎-CS prettyprint-覆盖>MINVALUE =新日期时间(0L,DateTimeKind.Unspecified);
但是,这不是一个真正的问题,这个定义序列化过程中带来的问题。 JSON序列化的DateTime通过完成:
<预类=郎-CS prettyprint-覆盖>System.Runtime.Serialization.Json.JsonWriterDelegator.WriteDateTime(日期时间值)
不幸的是它被定义为:
<前类=郎-CS prettyprint-覆盖>...
如果(value.Kind!= DateTimeKind.Utc)
{
长NUM = value.Ticks - TimeZone.CurrentTimeZone.GetUtcOffset(值).Ticks;
如果((NUM> DateTime.MaxValue.Ticks)||(NUM< DateTime.MinValue.Ticks))
{
掷DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR .GetString(JsonDateTimeOutOfRange),新ArgumentOutOfRangeException(值)));
}
}
...
所以它并没有考虑到
未指定
,将其视为本地
。为了避免这种情况,你可以定义自己的常量:
<预类=郎-CS prettyprint-覆盖>MinValueUtc =新日期时间(0L,DateTimeKind 。世界标准时间);
或
<预类=郎-CS prettyprint-覆盖>MinValueUtc = DateTime.MinValue.ToUniversalTime();
看起来怪异,当然,但它有助于。
I am experiencing issues with a WCF REST service. The wire object that I try to return has certain properties not set, resulting in DateTime.MinValue for properties of type DateTime. The service returns an empty document (with HTTP status 200 ???). When I try to call JSON serialization myself, the exception that is thrown is:
SerializationException: DateTime values that are greater than DateTime.MaxValue or smaller than DateTime.MinValue when converted to UTC cannot be serialized to JSON.
This can be reproduced by running the following code in a console app:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DateTime)); MemoryStream m = new MemoryStream(); DateTime dt = DateTime.MinValue; // throws SerializationException in my timezone ser.WriteObject(m, dt); string json = Encoding.ASCII.GetString(m.GetBuffer()); Console.WriteLine(json);
Why is this behaviour? I think it is related to my timezone (GMT+1). As DateTime.MinValue is default(DateTime), I would expect that this can be serialized without problems.
Any tips on how to make my REST service behave? I don't want to change my DataContract.
解决方案The main problem is
DateTime.MinValue
hasDateTimeKind.Unspecified
kind. It is defined as:MinValue = new DateTime(0L, DateTimeKind.Unspecified);
But this is not a real problem, this definition leads to problem during serialization. JSON DateTime serialization done through:
System.Runtime.Serialization.Json.JsonWriterDelegator.WriteDateTime(DateTime value)
Unfortunately it is defined as:
... if (value.Kind != DateTimeKind.Utc) { long num = value.Ticks - TimeZone.CurrentTimeZone.GetUtcOffset(value).Ticks; if ((num > DateTime.MaxValue.Ticks) || (num < DateTime.MinValue.Ticks)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString("JsonDateTimeOutOfRange"), new ArgumentOutOfRangeException("value"))); } } ...
So it doesn't take into account
Unspecified
and treats it asLocal
. To avoid this situation you can define your own constant:MinValueUtc = new DateTime(0L, DateTimeKind.Utc);
or
MinValueUtc = DateTime.MinValue.ToUniversalTime();
It looks weird of course, but it helps.
这篇关于为什么DateTime.MinValue不UTC时区提前进行序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!