Deserializing an object containing a Guid will result in a null value, even if the json string and Guid is correctly formatted.
Deserializing the same object using Newtonsoft.Json is successful and gives the expected object.
//SystemApplication is an object containing a Guid-property and several string-properties
var response = await httpClient.GetAsync($"v1/some/endpoint");
var content = await response.Content.ReadAsStringAsync();
var result_SystemText = System.Text.Json.JsonSerializer.Deserialize<SystemApplication>(content); //Will result in null-object
var result_Newtonsoft = Newtonsoft.Json.JsonConvert.DeserializeObject<SystemApplication(content); //Will result in correctly serialized object
### dotnet --info
PS C:windowssystem32> dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 3.0.100
Commit: 04339c3a26
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:Program Filesdotnetsdk3.0.100
Host (useful for support):
Version: 3.0.0
Commit: 7d57652f33
.NET Core SDKs installed:
2.1.802 [C:Program Filesdotnetsdk]
2.2.402 [C:Program Filesdotnetsdk]
3.0.100 [C:Program Filesdotnetsdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.13 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.13 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:Program FilesdotnetsharedMicrosoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.13 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0 [C:Program FilesdotnetsharedMicrosoft.WindowsDesktop.App]
@RasmusWesterlundh can you provide a snippet of your content payload (particularly the showing the Guid format (see remarks section)), and if possible your SystemApplication class schema?
Hi @layomia,
The only content-payload I have at the moment is with sensitive system information from production data, so I cannot share that with you. I hope this should be fairly easy to replicate none-the-less.
In the content-payload the Guid is 32 digits separated with hyphens ("D"-specifier).
In the successful deserialization by Newtonsoft.Json that same value is however noted as 32-digits separated by hyphens, enclosed in bracers ("B"-specifier).
@RasmusWesterlundh - can you provide a simplified/anonymized repro of your issue by extracting that out from your specific application (removing/replacing any sensitive info)?
Does your class schema contain public properties with getters and setters? Only those are supported.
Is there a property name mismatch in the payload vs your class schema (maybe casing difference)?
Does your JSON payload contain the Guid in the "B" format, i.e. surrounded by braces? The JsonSerializer by default uses the "D" format for parsing, and hence would fail for other formats. If you need to support custom formats, you'd need to write your own Guid converter (similar to when you need to support different date time formats: https://docs.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support
This works as expected:
```C#
[Fact]
public static void GuidDeserializationTest()
{
Foo f = JsonSerializer.Deserialize
Guid expected = new Guid("090bbc52-bfe3-4fa3-9b36-25d7e624e662");
Assert.Equal(expected, f.MyGuid);
}
public class Foo
{
public Guid MyGuid { get; set; }
}
```
The Guid is in "D"-format in the json payload.
No naming mismatches, I doubt I that the Newtonsoft deserializer would have managed to deserialize if that had been the case.
Edit: I'm sorry, my previous testing of this must have been very incomplete. It is not related to the Guid at all it seems. Removing the Guid property from the class object and removing it from the content string still results in the System.Text.JsonSerializer to fail the deserialization.
Newtonsoft still manages to deserialize.
I just got the feeling that this maybe belongs to StackOverflow instead 馃槄
string content = "{\"data\":{\"Type\":\"Foo\",\"Description\":\"bar \",\"Software\":\"baz\",\"Version\":\"qux\",\"Url\":\"http://example.com\",\"DatabasePortNumber\":1,\"Id\":\"2cdc66f1-0000-0000-39ac-233c00000000\"}}";
var result_SystemText = System.Text.Json.JsonSerializer.Deserialize<SystemApplicationResponse>(content); //Will result in null-object
var result_Newtonsoft = Newtonsoft.Json.JsonConvert.DeserializeObject<SystemApplicationResponse>(content); //Will result in correctly serialized object
```cs
public class SystemApplicationResponse
{
public SystemApplicationDto Data { get; set; }
}
public class SystemApplicationDto
{
public SystemApplicationDtoType Type { get; set; }
public string Description { get; set; }
public string Software { get; set; }
public string Version { get; set; }
public string Url { get; set; }
public int DatabasePortNumber { get; set; }
public System.Guid Id { get; set; }
}
public enum SystemApplicationDtoType
{
Foo = 0
}
No naming mismatches, I doubt I that the Newtonsoft deserializer would have managed to deserialize if that had been the case.
The very first property (data) in your JSON doesn't match the property name (Data) 馃檲
@khellang
You are correct. Changing it to an uppercase results in System.Text throwing an error on trying to deserialize the SystemApplicationDtoType.
But at this point it is very apparent that this belongs to StackOverflow rather than as a github issue.... 馃檭
Changing it to an uppercase results in System.Text throwing an error on trying to deserialize the SystemApplicationDtoType.
System.Text.Json.JsonException : The JSON value could not be converted to System.Text.Json.Serialization.Tests.ReadValueTests+SystemApplicationDtoType. Path: $.Data.Type | LineNumber: 0 | BytePositionInLine: 21.
That's likely because you are deserializing an enum with string values (the default only supports integer values for enums). Register the JsonStringEnumConverter as part of JsonSerializerOptions to get the expected behavior.
```C#
var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());
var result_SystemText = JsonSerializer.Deserialize
```
Edit: I'm sorry, my previous testing of this must have been very incomplete. It is not related to the Guid at all it seems. Removing the Guid property from the class object and removing it from the content string still results in the System.Text.JsonSerializer to fail the deserialization.
I suspected that.
But at this point it is very apparent that this belongs to StackOverflow rather than as a github issue....
No problem. I am glad the issue got resolved :)
Most helpful comment
The very first property (
data) in your JSON doesn't match the property name (Data) 馃檲