我有一个来自对象的JSON调用:
public record SaveDate(DateOnly StartDate, string EndDate, Object[] objects);
var saveDate= new SaveDate(DateOnly.MinValue, DateTime.MaxValue.ToString("yyyy-MM-dd"),
new Object[] { objects});
当执行API调用时,它最终返回
{
"startDate": {
"year": 1,
"month": 1,
"day": 1,
"dayOfWeek": 1,
"dayOfYear": 1,
"dayNumber": 0
},
"endDate": "2022-07-07",
"Object": [
{
"foo": "bar"
}
]
}
]
}
然而,我需要从startDate发送的格式与endDate("yyyy-MM-dd"(相同,而不是反序列化版本。我该怎么做?
注意:我使用DateOnly作为类型(.net6.0(,API需要上面指定格式的字符串。
DateOnly
和TimeOnly
绑定尚未完全支持。您可以为这种类型实现自己的转换器:
public class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
private const string Format = "yyyy-MM-dd";
public override DateOnly ReadJson(JsonReader reader,
Type objectType,
DateOnly existingValue,
bool hasExistingValue,
JsonSerializer serializer) =>
DateOnly.ParseExact((string)reader.Value, Format, CultureInfo.InvariantCulture);
public override void WriteJson(JsonWriter writer, DateOnly value, JsonSerializer serializer) =>
writer.WriteValue(value.ToString(Format, CultureInfo.InvariantCulture));
}
class MyClass
{
[JsonConverter(typeof(DateOnlyJsonConverter))]
public DateOnly dt { get; set; }
}
// prints {"dt":"2021-01-01"}
Console.WriteLine(JsonConvert.SerializeObject(new MyClass{dt = new DateOnly(2021,1,1)}));
对于System.Text.Json
,请参见此答案。
UPD
最近发布的13.0.2版本的Newtonsoft.Json
支持DateOnly
和TimeOnly
:
13.0.2
新增功能-增加对DateOnly和TimeOnly 的支持
对于.NET 6,我不得不稍微更新Gugu Stron的答案:
public class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
private const string Format = "yyyy-MM-dd";
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateOnly.ParseExact(reader.GetString(), Format, CultureInfo.InvariantCulture);
}
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(Format, CultureInfo.InvariantCulture));
}
}
用法相同:
class MyClass
{
[JsonConverter(typeof(DateOnlyJsonConverter))]
public DateOnly dt { get; set; }
}
我在一个F#项目中遇到了这个问题。这是F#等价的
type DateOnlyJsonConverter() =
inherit JsonConverter<DateOnly>()
let format = "yyyy-MM-dd"
override this.WriteJson(writer: JsonWriter, value: DateOnly, _: JsonSerializer): unit =
writer.WriteValue(value.ToString(format, CultureInfo.InvariantCulture))
override this.ReadJson(reader, _, _, _, _) =
DateOnly.ParseExact(reader.Value :?> string, format, CultureInfo.InvariantCulture)
type TimeOnlyJsonConverter() =
inherit JsonConverter<TimeOnly>()
let format = "HH:mm:ss.FFFFFFF"
override this.WriteJson(writer: JsonWriter, value: TimeOnly, _: JsonSerializer): unit =
writer.WriteValue(value.ToString(format, CultureInfo.InvariantCulture))
override this.ReadJson(reader, _, _, _, _) =
TimeOnly.ParseExact(reader.Value :?> string, format, CultureInfo.InvariantCulture)
如何使用:
type Person = {
Name: string
BirthDate: DateOnly
}
let json = JsonConvert.SerializeObject(person, Formatting.None, DateOnlyJsonConverter())
(* result:
{ "name": "Ken", "birthDate": "1987-05-20" }
*)
将在13.0.2中添加对DateOnly和TimeOnly的支持,该版本目前处于Beta 2中。在早期版本中,应用程序应该使用自定义JSON转换器。
STJ和Newtonsoft已经支持DateOnly
和TimeOnly
。更新您的NuGet软件包。