English 中文(简体)
System Text JsonSerializer Deserialization of TimeSpan
原标题:

In researching how to deserialize a TimeSpan using Newtonsoft s JSON.net I came across code in my current project that did not use Json.net. It used System.Text.Json.JsonSerializer and appeared to not fail on the operation of deserializing the TimeSpan property, as per the unit tests I was running.

Great I thought, .Net Core 3.1 has surpassed the historical issue of deserializing a TimeSpan and all is good. So fired up a test case in the latest version of Linqpad 6 (which uses .NET Core) to verify and to my chagrin it failed.


So the question is, can the TimeSpan be serialized/deserialized using either library (and if so how)… or is my test case below flawed in some respect?


Code

public class Project { public TimeSpan AverageScanTime { get; set; } }

Linqpad C# Code

var newP = new Project() { AverageScanTime = TimeSpan.FromHours(1) };

newP.Dump("New one");

var json = System.Text.Json.JsonSerializer.Serialize(newP);

json.Dump("JSON serialized");

System.Text.Json.JsonSerializer.Deserialize<Project>(json)
                               .Dump("JSON Deserialize");

Deserialize Failure

enter image description here

最佳回答

JsonSerializer for TimeSpan seem will added in Future (removed from .NET 6 milestone). You can trace this issue in Future milestone or this issue.

Before the end of 2022, you need implement JsonTimeSpanConverter on your own. Or you can install Macross.Json.Extensions nuget package and follow the instruction to de/serializer.

At this time, with .NET 6, you can use the build-in Serialize method to serialize and deserialize objects. As below:

System.Text.Json.JsonSerializer.Serialize(
    new { Time = TimeSpan.FromSeconds(100) }
);
// Output:
// {"Time":"00:01:40"}
问题回答

An addition to the answer from Poy Chang

Swagger (Swashbuckle) also requires a configuration

services.AddSwaggerGen(options =>
{
    options.MapType(typeof(TimeSpan), () => new OpenApiSchema
    {
        Type = "string",
        Example = new OpenApiString("00:00:00")
    });
});

TimeSpanConverter is available in .NET 6.0. So TimeSpan serialization/deserialization will work without custom converters out of the box.

Issue: https://github.com/dotnet/runtime/issues/29932

Implementation: https://github.com/dotnet/runtime/pull/54186





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签