❔ Does System.Text.Json.JsonSerializer allow members to be serialized or do I need properties?

The problem is that my properties commonly have set accessors that do things like mark the item dirty. You can't have a property with both set and init, or am I misunderstanding something?
20 Replies
Will Pittenger
Will PittengerOP14mo ago
For me, set is also firing off events. So what should I do?
Thinker
Thinker14mo ago
Your serialization DTO really shouldn't be firing events
Will Pittenger
Will PittengerOP14mo ago
init would just set the field. Nothing else. Which is why I was trying to put the [JsonInclude] attribute on the field. But I'm getting an exception.
Thinker
Thinker14mo ago
no I mean you should ideally be deserializing your json to a separate dto type which you then create your actual entity/model/whatever from anyway what's the exception?
Will Pittenger
Will PittengerOP14mo ago
The non-public property 'strName' on type 'BestChat.IRC.Data.Defs.Network' is annotated with 'JsonIncludeAttribute' which is invalid.' Well, I'm looking into initializing from a JsonElement, but I don't see a good way to simply test if a property exists. I was hoping to do something like x = element.HasProperty(nameof(x)) ? element.GetProperty(nameof(x)) : default;. I can't use an enumerator as some fields might be missing from the file and need to be explicitly defaulted before the constructor exits.
MODiX
MODiX14mo ago
Thinker
REPL Result: Success
record PersonDto(string Name, int Age);

class Person
{
private string _name;
private int _age;

public string Name
{
get => _name;
set
{
Console.WriteLine("set name");
_name = value;
}
}

public int Age
{
get => _age;
set
{
Console.WriteLine("set age");
_age = value;
}
}

public Person(PersonDto dto) => (_name, _age) = (dto.Name, dto.Age);
}

var json = """{"Name":"John Doe","Age":41}""";

var dto = System.Text.Json.JsonSerializer.Deserialize<PersonDto>(json);
var person = new Person(dto);

person.Age = 42;

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
record PersonDto(string Name, int Age);

class Person
{
private string _name;
private int _age;

public string Name
{
get => _name;
set
{
Console.WriteLine("set name");
_name = value;
}
}

public int Age
{
get => _age;
set
{
Console.WriteLine("set age");
_age = value;
}
}

public Person(PersonDto dto) => (_name, _age) = (dto.Name, dto.Age);
}

var json = """{"Name":"John Doe","Age":41}""";

var dto = System.Text.Json.JsonSerializer.Deserialize<PersonDto>(json);
var person = new Person(dto);

person.Age = 42;

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
Console Output
set age
Name: John Doe, Age: 42
set age
Name: John Doe, Age: 42
Compile: 812.406ms | Execution: 176.700ms | React with ❌ to remove this embed.
Thinker
Thinker14mo ago
is there a reason you can't do something akin to this?
Will Pittenger
Will PittengerOP14mo ago
Don't know. Looks like I have no place with that simple syntax to use [JsonRequired].
Thinker
Thinker14mo ago
record Person([property: JsonRequired] string Name, int Age);
record Person([property: JsonRequired] string Name, int Age);
Will Pittenger
Will PittengerOP14mo ago
Does putting a default on that have an effect?
record Person(string Name, int Age =3);
record Person(string Name, int Age =3);
Thinker
Thinker14mo ago
yeah, if you don't provide a value then it'll use that value by default
MODiX
MODiX14mo ago
Thinker
REPL Result: Success
record Person(string Name, int Age = 3);

var json = """{"Name":"John Doe"}""";

System.Text.Json.JsonSerializer.Deserialize<Person>(json)
record Person(string Name, int Age = 3);

var json = """{"Name":"John Doe"}""";

System.Text.Json.JsonSerializer.Deserialize<Person>(json)
Result: Person
{
"name": "John Doe",
"age": 3
}
{
"name": "John Doe",
"age": 3
}
Compile: 647.087ms | Execution: 86.095ms | React with ❌ to remove this embed.
Will Pittenger
Will PittengerOP14mo ago
Is the serializer supposed to convert enums for you? The value matches a value from the enum type for a field, but it's throwing an exception. Though it's reporting the line before the enum value.
Thinker
Thinker14mo ago
Is the enum value in the json a string or number?
Will Pittenger
Will PittengerOP14mo ago
string.
Thinker
Thinker14mo ago
In that case you'll have to add a JsonStringEnumConverter to the converter in the json settings Or if you're using .NET 8 then you can use the generic version JsonStringEnumConverter<YourEnum>
Will Pittenger
Will PittengerOP14mo ago
I don't see a JsonStringEnumConverter. Is .NET 8 out?
Thinker
Thinker14mo ago
System.Text.Json.Serialization.JsonStringEnumConverter Comes out in November but release candidate 1 is out
Will Pittenger
Will PittengerOP14mo ago
OK. Well, now it thinks some required properties are missing. I don't think they are missing. I took out the [JsonRequired] for the moment so I could get it up. Seems to work that way. I don't understand why it thought it the required fields were missing. It filled them just fine.
Accord
Accord14mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server