- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我的 ASP.NET Core Web-API 项目中,我收到了对我的一个 API Controller 的 HTTP POST 调用。
在评估 JSON 负载并反序列化其内容时,Json.NET 偶然发现了 0001-01-01T00:00:00
的 DateTime 值,并且无法将其转换为 DateTimeOffset 属性。
我注意到该值应该代表 DateTimeOffset.MinValue 的值,但它缺少时区似乎会使解串器出错。我只能想象 DateTimeOffset.Parse 会尝试将其转换为主机当前时区,这会导致 DateTimeOffset.MinValue 下溢。
这个属性非常简单:
[JsonProperty("revisedDate", NullValueHandling = NullValueHandling.Ignore)]
public DateTimeOffset? RevisedDate { get; set; }
这是发送给客户端的响应:
{
"resource.revisedDate": [
"Could not convert string to DateTimeOffset: 0001-01-01T00:00:00. Path 'resource.revisedDate', line 20, position 44."
]
}
我正在使用 Newtonsoft.Json v11.0.2,目前处于 UTC + 2(德国)。异常回溯和错误消息在这里:https://pastebin.com/gX9R9wq0 .
我无法修复调用代码,所以我必须在我这边修复它。
但问题是:怎么做?
最佳答案
问题 似乎只有在机器的时区 TimeZoneInfo.Local
时才能重现与 UTC 有正偏移,例如(UTC+01:00) 阿姆斯特丹、柏林、伯尔尼、罗马、斯德哥尔摩、维也纳
。我无法在具有非正偏移量的时区重现它,例如 UTC-05:00
或 UTC 本身。
具体来说,在 JsonReader.ReadDateTimeOffsetString()
使用 DateTimeStyles.RoundtripKind
调用 DateTimeOffset.TryParse
:
if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
{
SetToken(JsonToken.Date, dt, false);
return dt;
}
这显然会导致具有正 UTC 偏移量的时区出现下溢错误。如果在调试器中我使用 DateTimeStyles.AssumeUniversal
进行解析,则可以避免该问题。
您可能想要 report an issue关于这个给 Newtonsoft。只有当计算机的时区具有特定值时,特定 DateTimeOffset
字符串的反序列化才会失败这一事实似乎是错误的。
解决方法是使用 IsoDateTimeConverter
使用 IsoDateTimeConverter.DateTimeStyles
反序列化您的 DateTimeOffset
属性设置为 DateTimeStyles.AssumeUniversal
。此外,有必要通过设置 JsonReader.DateParseHandling = DateParseHandling.None
来禁用 JsonReader
内置的自动 DateTime
识别功能。 ,这必须在阅读器开始解析您的 DateTimeOffset
属性的值之前完成。
首先,定义如下JsonConverter
:
public class FixedIsoDateTimeOffsetConverter : IsoDateTimeConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?);
}
public FixedIsoDateTimeOffsetConverter() : base()
{
this.DateTimeStyles = DateTimeStyles.AssumeUniversal;
}
}
现在,如果您可以修改 Controller 的 JsonSerializerSettings
,请使用以下设置:
var settings = new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.None,
Converters = { new FixedIsoDateTimeOffsetConverter() },
};
如果您不能轻松修改 Controller 的JsonSerializerSettings
,则需要从this answer 获取DateParseHandlingConverter
给 How to prevent a single object property from being converted to a DateTime when it is a string 并将其与 FixedIsoDateTimeOffsetConverter
一起应用于您的模型,如下所示:
[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)]
public class RootObject
{
[JsonProperty("revisedDate", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(FixedIsoDateTimeOffsetConverter))]
public DateTimeOffset? RevisedDate { get; set; }
}
DateParseHandlingConverter
必须应用于模型本身而不是 RevisedDate
属性,因为 JsonReader
已经识别出 0001-01 -01T00:00:00
作为调用 FixedIsoDateTimeOffsetConverter.ReadJson()
之前的 DateTime
。
更新
在comments , @RenéSchindhelm写道,我创建了一个问题让 Newtonsoft 知道。它是 Deserialization of DateTimeOffset value fails depending on system's timezone #1731 .
关于c# - 对于没有时区的 DateTimeOffset.MinValue,Json.NET 反序列化 DateTimeOffset 值失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50628374/
如何从 DateTimeOffsetDateTimeOffset 对象中提取日期?我认为 Date 属性只会返回日期部分。但是,我一直在获取整个日期,即 7/17/2014 12:00:00 AM -
如何计算可为空的 DateTimeOffset 之间的时间?到 DateTimeOffset.Now ? 我需要像“x 天 y 小时前”这样的结果 我是从做这样的事情开始的。 var creati
在我的 ASP.NET Core Web-API 项目中,我收到了对我的一个 API Controller 的 HTTP POST 调用。 在评估 JSON 负载并反序列化其内容时,Json.NET
我从具有多个 datetimeoffet 列的表中选择一条记录,当我添加 for json auto 时,它将它从 2017-06-21 08:12:16.1430000 +00:00 到 2017-
我仍在学习 C# .NET 库,我该如何处理以下情况。如果有人能指导我正确的方向,将不胜感激。 最佳答案 您不能将空值分配给不可为空的值。解决此问题的一种方法是使用 ?? 添加默认(非空)值。 例如
我目前在 UTC+1 时区。 TimeZoneInfo.Local.BaseUtcOffset 返回 +1。 new DateTimeOffset(DateTime.Today).AddDays(4)
我想将默认值设置为 DateTimeOffset - 它不应该是 DateTime.Now 而是 DateTime.MinValue 或 default(DateTime) 任何想法我该怎么做?这段代
我有这些输入字符串: var timeStr = "03:22"; var dateStr = "2018/01/12"; var format = "yyyy/MM/dd"; var timeZon
如果我有一个表示有效 UTC 时间的 DateTime 实例,以及一个将 DateTime 转换为它适用的时区的偏移量,我该如何构造一个 DateTimeOffset 实例来表示它? var utcD
我正在使用 Quartz.NET( http://quartznet.sourceforge.net/ ) 并且我试图将开始日期设置为午夜。但是我在创建这个日期时遇到了问题。该应用程序将位于不同时区的
我遇到了以下要求的有趣问题:测试进程是否在同一天运行,如果没有运行进程。日期存储为 DataTimeOffset。 我最初的做法是: 将这两个值都转换为 UTC,因为这些日期可能是在不同的时区创建的并
我想从一个字符串中创建一个新的DateTimeOffset offset = -5 我愿意: string dt = "11082016"; DateTime date = DateTime.P
我在理解 DateTimeOffset 时遇到一些问题... 我正在尝试为 Quartz-Job 创建一个简单的触发器。存在一个 triggerbuilder,可以使用它创建这样的触发器: var t
我想从 DateTimeOffset 类型中获取格式化字符串,它应该如下所示:20. July 2009。(带点),我尝试使用以下代码: Birthday.ToString("dd. MMMM yyy
我阅读了有关 DateTimeOffset、属性 DateTime 的文档。 https://msdn.microsoft.com/en-us/library/system.datetimeoffse
我正在使用 C# 驱动程序在我的集合中存储 DateTimeOffset 字段。我想按一段时间对值进行分组,即。按天。 为此,我正在做类似的事情: db.getCollection('Collecti
我们正在将 XML DateTime 值解析为 DateTimeOffset 值。根据W3C XSD documentation for DateTime ,该类型可能有或没有时区信息。 我们的要求是
我有一个 DateTimeOffSet 类型的变量。我想过滤所有在 2010 年 1 月 1 日之后创建的项目。 所以我写了下面的查询: var _date = new DateTimeOffs
我将时间表作为一周中的一天、小时和分钟存储在数据库中。读取数据后,我们为下一次出现的那一天、小时和分钟创建一个 DateTime 对象,但我需要修改它以支持 DST。如有必要,我可以修改数据库。 我知
有没有办法将 DateTimeOffset 转换为午夜后的分钟数? 我希望偏移部分反射(reflect)在它给出的答案中。 最佳答案 dateTimeOffset.UtcDateTime.TimeOf
我是一名优秀的程序员,十分优秀!