我的数据库中的日期存储为Utc。但是当我用实体框架来修复它们时,它们就是未指定的类型。
当JSON.Net序列化它们时,它们不是Utc格式。有没有办法告诉JSON.Net将DateTimes序列化为Utc,即使它们的类型未指定为Utc?
答案 0 :(得分:100)
将DateTimeZoneHandling
上的JsonSerializerSettings
设置为Utc
。这将在序列化之前将所有日期转换为UTC。
public void SerializeObjectDateTimeZoneHandling()
{
string json = JsonConvert.SerializeObject(
new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});
Assert.AreEqual(@"""2000-01-01T01:01:01Z""", json);
}
答案 1 :(得分:1)
正如@dez在评论中提到的那样,您可以直接从.NET代码中直接在.net代码中将DateTime对象“标记”为UTC,然后再从数据库中加载它们并进行序列化之前:
<%= javascript_include_tag "application" %>
答案 2 :(得分:0)
对我来说,为DateTime属性创建UTC转换器(基于Newtonsoft.Json.Converters.IsoDateTimeConverter的实现)更为简单。
public class UtcJsonDateTimeConverter : DateTimeConverterBase
{
private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFZ";
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string text;
if (value is DateTime dateTime)
{
text = dateTime.ToString(DefaultDateTimeFormat, CultureInfo.InvariantCulture);
}
else
{
throw new JsonSerializationException(
$"Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {value.GetType()}.");
}
writer.WriteValue(text);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
bool nullable = objectType == typeof(DateTime?);
if (reader.TokenType == JsonToken.Null)
{
if (!nullable)
{
throw new JsonSerializationException($"Cannot convert null value to {objectType}.");
}
return null;
}
if (reader.TokenType == JsonToken.Date)
{
return reader.Value;
}
else if (reader.TokenType != JsonToken.String)
{
throw new JsonSerializationException($"Unexpected token parsing date. Expected String, got {reader.TokenType}.");
}
string date_text = reader.Value.ToString();
if (string.IsNullOrEmpty(date_text) && nullable)
{
return null;
}
return DateTime.Parse(date_text, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
}
public class SomeEntity
{
[JsonProperty(PropertyName = "id", Order = 1)]
public int ID { get; set; }
[JsonProperty(PropertyName = "created", Order = 2)]
[JsonConverter(typeof(UtcJsonDateTimeConverter))]
public DateTime Created { get; set; }
}
答案 3 :(得分:0)
我使用了可接受的答案,但是将其应用于默认设置:
JsonConvert.DefaultSettings = (() =>
{
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
settings.Formatting = Formatting.Indented;
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
return settings;
});