-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dotnet 7 System.Text.Json JsonSerializer.Serialize exception: is marked required but does not specify a setter. #82879
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsDescriptionusing JsonSerializer.Serialize to Serialize object. Reproduction Stepsusing System.Text.Json;
using System.Text.Json.Serialization;
TestDto t = new() { Items = new() };
string jsonString = JsonSerializer.Serialize(t);
Console.WriteLine(jsonString);
public class TestDto
{
public string? Field1 { get; set; }
[JsonIgnore]
public required List<string> Items { get; set; }
} Expected behaviorno exception Actual behaviorexception throws Regression?No response Known WorkaroundsNo response ConfigurationNo response Other informationNo response
|
I believe this is by design. The |
using Newtonsoft.Json;
TestDto t = new() { Field1 = "Value1", Items = new() };
List<TestDto> ts = new() { t };
string json = JsonConvert.SerializeObject(t);
Console.WriteLine();
public class TestDto
{
public required string Field1 { get; set; }
[JsonIgnore]
public required List<string> Items { get; set; }
} when using Newtonsoft.Json it works |
The property is required for object initialization (what the required keyword mean), but not required for json serialization. They are two different things. |
I would guess that's because Json.NET doesn't support |
They are not. Deserialization if anything does perform object initialization, albeit indirectly. You can always bypass required/init properties when using reflection (which is why you see this working in the case of Json.NET), however you can't do it in the case of source generators. STJ honors |
Deserialization throws exception make sense. since deserialization will create object, and the required modifier should be respected. But serialization is object to json. The object is already created(required modifier was also respected). Serialization throw exception make people confuse, since it doesn't create object, it only create string from concat object properties. I meet this issue when I want to return dictionary as json to frontend, but I don't want to return the original list (duplicate). using System.Text.Json;
using System.Text.Json.Serialization;
SomeVm vm = new() { SomeDtos = new() };
foreach (var dto in vm.SomeDtos)
{
dto.ItemsDict = dto.Items
.ToDictionary(i => i.Key, i => i);
}
string jsonString = JsonSerializer.Serialize(vm);
Console.WriteLine(jsonString);
public class SomeVm
{
public required List<SomeDto> SomeDtos { get; set; }
public string? Field1 { get; set; }
}
public class SomeDto
{
public string? Field1 { get; set; }
[JsonIgnore]
public required List<SomeItemDto> Items { get; set; }
public Dictionary<string, SomeItemDto>? ItemsDict { get; set; }
}
public class SomeItemDto
{
public required string Key { get; set; }
public string? Value { get; set; }
} Thanks for your help. |
JsonIgnoreAttribute is not specific to serialization -- it also controls deserialization. It's precisely this mode (disabling deserialization for a property marked required) that triggers the error you are seeing. |
Maybe JsonIgnore should have higher priority than C# required modifier? If have JsonIgnore , then required is omitted. Or we should have more detailed documentation. |
That's not something that would work with the source generator.
Does this work? https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/required-properties |
The page talks about JsonSerializer.Deserialize will throw exception, but doesn’t mention JsonSerializer.Serialize |
The error stems from validating the JSON contract for the type, which happens during both serialization and deserialization operations. |
@kzhui125 you can use this workaround to fix this for reflection serializer: The reason this is not working by default is because that will never work with source gen since it needs to generate constructor and that code won't compile without required property. I'll close this issue as by design because the fact serializer can workaround this doesn't mean it's the right thing to do. |
Description
using JsonSerializer.Serialize to Serialize object.
Reproduction Steps
Expected behavior
no exception
Actual behavior
exception throws
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: