我正在开发一个简单的Web API客户端。我的模型中有一个show
属性,我已将其指定为ExpiresOn
。
DateTimeOffset
我使用public class Model {
public DateTimeOffset ExpiresOn { get; set; }
}
从JSON字符串反序列化API响应。我注意到,由于我检索的JSON没有指定任何时区信息,因此JSON.Net将假定它是本地时间,并根据我的设置返回一个调整为UTC的JsonConvert.DeserializeObject<T>()
。我尝试了不同的组合,但是似乎无法“强制” DateTimeOffset
来读取字符串,就好像它是UTC一样。
最好有一个选项可以使用JsonConvert
全局设置该设置,因为我要在多个位置进行类似的解析。
此外,我正在为ASP.Net Core 2.1进行编码,并且主机的tz设置为CEST(+02:00)。不能在主机上设置其他时区。
附录:
要解析的JsonConvert.DefaultSettings
的示例为string
。我尝试过"2018-07-09T11:22:33.45678"
和DateParseHandling
的排列,但是都返回一个日期:DateTimeZoneHandling
。
很明显,反序列化器假定该字符串位于本地时间。因此,是否有一种方法可以像对待2018-07-09T11:22:33.45768+02:00
中的AssumeUniversal
一样对待它?
答案 0 :(得分:1)
似乎DateTimeZoneHandling
对DateTimeOffset
不起作用。
作为解决方法,您必须定义一个JsonConverter
来解决此问题:
public class DateTimeOffsetConverter : Newtonsoft.Json.JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTimeOffset);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null) return null;
DateTime dateTime = (DateTime)reader.Value;
return new DateTimeOffset(dateTime);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value);
}
}
然后像这样使用它:
public class Model
{
[JsonConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset ExpiresOn { get; set; }
}
然后这样称呼它:
var str = "{\"ExpiresOn\":\"2018-07-09T11:22:33.45678\"}";
Model test = JsonConvert.DeserializeObject<Model>(str, new JsonSerializerSettings()
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
DateParseHandling = DateParseHandling.DateTime
});
Assert(test.ExpiresOn.Offset.Ticks == 0);
您也可以在JsonSerializerSettings
中定义JsonConvert.DefaultSettings
,而不是每个转换调用。
答案 1 :(得分:0)
根据文档,您可以通过DateTimeZoneHandling
传递JsonSerializerSettings
Here是该示例,尽管此处的示例用于序列化,但是您可以通过相同的设置进行反序列化,也可以查看this
示例:-
string jsonWithUtcTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
反序列化示例:
JsonSerializerSettings settings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
};
var json = JsonConvert.SerializeObject(a, settings);
var newA = JsonConvert.DeserializeObject<A>(json, settings);