C
C#12mo ago
LPeter1997

❔ Avoid infinite recursion in STJ converters

There are so-so many cases where I only want to customize reading up a type in System.Text.Json, but I'd want the default behavior for writing. Currently I'm doing this to avoid SO:
public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options)
{
// TODO: Ugly hack, can we avoid recursion in a nicer way?
// Remove this converter
var newOptions = new JsonSerializerOptions(options);
for (var i = options.Converters.Count - 1; i >= 0; --i)
{
if (options.Converters[i].GetType() == this.GetType()
|| options.Converters[i].GetType() == typeof(ModelInterfaceConverter))
{
newOptions.Converters.RemoveAt(i);
}
}

// Default behavior
JsonSerializer.Serialize(writer, value, newOptions);
}
public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options)
{
// TODO: Ugly hack, can we avoid recursion in a nicer way?
// Remove this converter
var newOptions = new JsonSerializerOptions(options);
for (var i = options.Converters.Count - 1; i >= 0; --i)
{
if (options.Converters[i].GetType() == this.GetType()
|| options.Converters[i].GetType() == typeof(ModelInterfaceConverter))
{
newOptions.Converters.RemoveAt(i);
}
}

// Default behavior
JsonSerializer.Serialize(writer, value, newOptions);
}
This is janky as hell IMO, is there a better/nicer way? I've found no obvious answer to it.
16 Replies
ero
ero12mo ago
Well, you're not really meant to use JsonSerializer.Serialize in a converter. The whole idea of it is that you specify how things are serialized.
LPeter1997
LPeter199712mo ago
Cool but that doesn't answer my question I don't want to specify how the given type is serialized, I only want to customize the reading part
ero
ero12mo ago
What...? Your post only ever talks about writing data, but now you ask about reading it?
LPeter1997
LPeter199712mo ago
facepalm post is about avoiding all that BS in Write I have customized Reading To avoid SO, I have to remove my converter for writing, because I do want the default write behavior
There are so-so many cases where I only want to customize reading up a type in System.Text.Json, but I'd want the default behavior for writing. Currently I'm doing this to avoid SO
provides snippet with the obvious hack
is there a better/nicer way?
Please take your usual useless comments elsewhere 😅
ero
ero12mo ago
?
cap5lut
cap5lut12mo ago
when looking at all the different overloads i would guess thats exactly what to use to get back to the default behavior. so where is that information from so i can read up on the details on it? thb, this all sounds like u basically should just use different JsonSerializerOptions for serialization and deserialization in first place and let it throw NotSupportedException on Write (1) the type checks in there are a bit weird as well imo, if u want to write it like this, each converter should have to deal only with itself, the condition seems to take care of more which has imo to much of an side effect here (2) imo (1) would be the much cleaner way and it will also reduce the gc stress
LPeter1997
LPeter199712mo ago
Yes, using different options for the 2 is pretty fair, I haven't thought about that I'll do that, thanks, it's essentially just one factory difference from reading The type-checks were in for safety tbh, since I didn't know if the converters made by the factory get inserted. Prolly not but I was paranoid, I had to test on an env where I had almost no way of debugging (and could repro there only...) Once I found the problem I left both in
cap5lut
cap5lut12mo ago
i think there should be even an reference equality check usable
LPeter1997
LPeter199712mo ago
Likely yeah, I really don't know how factories behave in this case, I'll do some experimentation. But honestly, separating options just solves my problems as a whole
ero
ero12mo ago
it really depends on the data you're working with, but breaking up the converter into ones that have less responsibility may be an option.
record R(
[property: JsonConverter(...)] SomeType Foo,
SomeOtherType Bar);
record R(
[property: JsonConverter(...)] SomeType Foo,
SomeOtherType Bar);
instead of a converter on the entire record
cap5lut
cap5lut12mo ago
do u know what takes precedence here if u would have conflicting info on JsonSerializerOptions and the annotated version?
ero
ero12mo ago
hmm, conflicting? do you mean 2 different converters for the same type?
ero
ero12mo ago
what an inconsistent precedence
cap5lut
cap5lut12mo ago
(just saw if u scroll down a bit there, they even use JsonSerializer.Serialize() inside the Write() method theirself btw)
Accord
Accord12mo 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
More Posts
❔ how to export project to .exeHey I have a project I'm trying to export to .exe. I see a lot of videos but their layout looks diff❔ How to access a button from a different class?Hello. Recently, I was developing a project and decided to start splitting my code into separate fil✅ Trouble importing LoggerService namespace with ILoggerService in .NET Core APICould someone help me with this error? I can't import the LoggerService namespace no matter what I t✅ What's the easiest type of information storage?I'm new to C# and when I was starting out with Python, the first type of data storage I learned was Unable to create an object of type 'DBCSDBContext'. For the different patterns supported at design tHey I've developed an application using Entity Framework Core and PostgreSQL, and I've encountered a✅ Listview colorHow do i put a different color for a specific item of a listview?❔ Blazor TypeConverter Exception```csharp [TypeConverter(typeof(IListStringConverter))] public List<string> Accepted✅ Docker + Blazor + EF Core 7 + SQLite = __EFMigrationsHistory doesnt existHello everyone i am new to docker and i am attempting to containerize an existing project. I've got ✅ What is the best way to setup app configuration using IHostBuilder?I want to make a good building of my host configuration and make it convenient to use. My goal is to❔ ef migration merges 2 tables of same type?<:kekw:710973294886649956> so my dbcontext that has two seperate tables of "Char" classes results