将JSON从对象序列化为string/DateOnly



我有一个来自对象的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需要上面指定格式的字符串。

DateOnlyTimeOnly绑定尚未完全支持。您可以为这种类型实现自己的转换器:

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支持DateOnlyTimeOnly:

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已经支持DateOnlyTimeOnly。更新您的NuGet软件包。

相关内容

  • 没有找到相关文章

最新更新