【问题标题】:ASP.NET 4.5 OData serialize DateTime to Json missing timezoneASP.NET 4.5 OData 将 DateTime 序列化为缺少时区的 Json
【发布时间】:2013-08-12 13:44:45
【问题描述】:
当我从 Queryable 序列化结果时,我使用的是 OData 和 Web API 5.0,
DateTime 字段总是缺少时区,显示如下:
StartTime: "2013-08-12T10:00:00"
我发现了一点微软 OData 实现,似乎 OData 使用自己的消息编写器进行序列化,所以我无法配置序列化程序以生成正确的带有时区的日期时间字符串。
有人知道如何解决这个问题吗?
【问题讨论】:
标签:
json
datetime
odata
datacontractserializer
【解决方案1】:
如果你没有sql 2008或更高版本,你也可以将nhibernate中的数据类型设置为utcdatetime。然后它只是假设日期时间是 utc,无论如何这是存储日期时间的唯一有效方式
【解决方案2】:
“System.DateTime”类型不包含时区信息,获取时区需要使用“System.DateTimeOffset”。
例如:
var dateTime = new DateTime(...);
var dtOffset = new DateTimeOffset(dateTime, new TimeSpan());
var dtOffset2 = new DateTimeOffset(dateTime, new TimeSpan(1,0,0));
//Assuming your pc is in the timezone GMT (+00:00)
// if you .ToString() each of the above you should get something like this ...
dateTime: "2013-08-12T10:00:00"
dtOffset: "2013-08-12T10:00:00+00:00"
dtOffset2: "2013-08-12T10:00:00+01:00"
如果您在 Windows 中更改 PC 的时区,则更改将应用于上面的“dateTime”变量,默认情况下,变量“dtOffset”将使用 Windows 指定的时区,但在“dtOffset2”变量中我指定时区,以便始终固定为 +01:00。
OASIS 已从 OData 标准中删除了 DateTime,但我相信 Microsoft 已将其保留在其 OData 实现中,但他们的实现假定 Offset 是机器偏移量。
【解决方案3】:
经过一番调查,我发现问题不是由 OData 引起的。
问题是由于 NHibernate 从 SQLSERVER 数据库读取的 DateTime 属性没有包含 TimeZone 信息,所以没有这些信息 OData 只能生成没有 TimeZone 的日期字符串。
请参考此链接:It gives a very detail explain about NHibernate datetime problem
所以我对这个问题的解决方案是在 .NET 代码和 SQLSERVER 2008 中从 DateTime 切换到 DateTimeOffset 类型。然后在数据库中,DateTimeOffset 列保留 TimeZone 信息,当 NIBerate 读取时,它会将 TimeZone 信息传递给 .NET DateTimeOffset属性。
从 SQLSERVER 2008 开始支持 DateTimeOffset。