JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.8k stars 3.26k forks source link

wrong deserialize of the datetimeoffset #2003

Open mhamri opened 5 years ago

mhamri commented 5 years ago

coming from here

Describe the bug

i have a model like this

class MyModel{
    public DateTimeOffset? plannedStartDate {get;set;}
}

and an action like this

[HttpPost]
public IActionResult Get(MyModel activityUpdate){
}

and i'm sending request from angular as a json

    {
       "plannedStartDate": "2019-03-04T16:00:00.000Z"
    }

which contains a valid date

enter image description here

but what i'm getting in the api is wrong

enter image description here

if i inspet the variable in the immediate windows i can see that the offset couldnt' parse correctly enter image description here

i tried to change the mvc options to

service.AddMvc()
 .AddJsonOptions(opt=>
    opt.SerializerSettings.DateParseHandling=DateParseHandling.DateTimeOffset);

i also played with these options

DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Local

and

DateFormatHandling = DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Local, 
DateParseHandling = DateParseHandling.DateTimeOffset

which didn't help, i dont' think it's about deserialize options.

our staging server is using linux and we don't have this problem, but our production use IIS on windows server and have this problem. i am not sure if it's related on the OS. but if i try it on my local development(which is windows 10) aslo i'm facing the same bug.

To Reproduce

Steps to reproduce the behavior:

  1. Using this version of ASP.NET Core '2.2'
  2. use windows machine (this bug doesn't happen in linux)

Expected behavior

something like this shouldn't need to have custom modelbinder or custom serilizer implementation. i checked a lot of solutions in SO, but most ask to create a new serilizer or modelBinder which doesn't make sense. when the input is valid and model ask for datetimeoffset why the offset is truncated?

Additional context

Include the output of dotnet --info

.NET Core SDK (reflecting any global.json):
 Version:   2.2.104
 Commit:    73f036d4ac

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17763
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.2.104\

Host (useful for support):
  Version: 2.2.2
  Commit:  a4fd7b2c84

.NET Core SDKs installed:
  2.1.503 [C:\Program Files\dotnet\sdk]
  2.1.504 [C:\Program Files\dotnet\sdk]
  2.2.101 [C:\Program Files\dotnet\sdk]
  2.2.102 [C:\Program Files\dotnet\sdk]
  2.2.104 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Tornhoof commented 5 years ago

I'm not sure I follow your description. What is your expected result? Do you think that you should have, after deserialization, a date with a timezone for Singapore? But you're sending a value with a specific Timezone UTC (Z) and you're deserializing a DateTimeOffset which honors this timezone. The offset is not truncated, it specified via 'Z' to be UTC. If you don't like that you can either send the correct Timezone or change your model to use DateTime and change the knobs to do local TimeZone Handling (as you've already tried). But as https://www.newtonsoft.com/json/help/html/DatesInJSON.htm specified, those knobs don't work with DateTimeOffset.

mhamri commented 5 years ago

yes, you are right, it was a bug in my side, thanks for explanaing.