我正在向以下形式返回JSON的API服务请求:
{
"dateCreated": {
"date":8,
"day":4,
"hours":22,
"minutes":44,
"month":10,
"nanos":241000000,
"seconds":46,
"time":1194590686241,
"timezoneOffset":480,
"year":107
}
}
在这里time
是自Unix时期以来的毫秒数,所以这确实是我唯一要注意的属性。
可以编写一个自定义的json.net转换器,该转换器应将其化为
之类的东西public class ApiResponse
{
public ApiResponse(DateTimeOffset dateCreated)
{
DateCreated = dateCreated;
}
public DateTimeOffset DateCreated { get; }
}
(转换器将在对象的time
属性上调用DateTimeOffset.FromUnixTimeMilliseconds
。)
这是我到目前为止的代码:
public class ApiDateConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
{
return typeof(DateTimeOffset) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// What type is existingValue here? How do I get existingValue.time?
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
}
选项1 :您的ApiDateConverter
可以通过:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
dynamic jObject = JObject.Load(reader);
return DateTimeOffset.FromUnixTimeMilliseconds(jObject.time.Value);
}
选项2 :不使用自定义转换器:
public class DateSerialized
{
public int date { get; set; }
public int day { get; set; }
public int hours { get; set; }
public int minutes { get; set; }
public int month { get; set; }
public int nanos { get; set; }
public int seconds { get; set; }
public long time { get; set; }
public int timezoneOffset { get; set; }
public int year { get; set; }
}
public class ApiResponse
{
[JsonIgnore]
public DateTimeOffset DateCreated => DateTimeOffset.FromUnixTimeMilliseconds(DateSerialized.time);
[JsonProperty("dateCreated")]
private DateSerialized DateSerialized { get; set; }
}
肯定是可能编写json.net转换器以将JSON直接转换为您的域对象,但是我不建议这样做。
相反,我建议您创建一个反映数据的DTO(数据传输对象):
public class DateDto
{
public long Time { get; set; }
}
然后将json.net供应到此对象。
一旦有了它,就可以创建一个纯的.NET转换器,该转换器将DateDto
映射到DateTime
或您想要的任何结构(假设您正在使用Nodatime库,而不是.NET的DateTime
)。
这样做,您可以节省实现自定义挑选逻辑的头痛,并且您正在遵循 s solid:单个责任原则中的 s 。您有一个对象,其目的仅代表数据,而转换器将其转换为您的应用程序使用的任何内容。
它还增加了代码的可检验性。