C
C#•2y ago
Arkobat

Custom JSON serializer not working

Hello I have a custom serializer i cannot get to work. When I use the model in a controller, it just gives me null. It is the following class I try to serialize
public class ExternalId
{
public string Id { get; set; }
}
public class ExternalId
{
public string Id { get; set; }
}
I want to be able to use the following input
{
"id1": "a",
"id2": "b",
"id3": "3"
}
// to e.g. this class
public class MyDTO {
public ExternalId Id1 {get; set;}
public ExternalId Id2 {get; set;}
public ExternalId Id3 {get; set;}
}
{
"id1": "a",
"id2": "b",
"id3": "3"
}
// to e.g. this class
public class MyDTO {
public ExternalId Id1 {get; set;}
public ExternalId Id2 {get; set;}
public ExternalId Id3 {get; set;}
}
This is my serializer. Is should just take the string, and wrap it in a ExternalId I have tried to put break points in here also, but they are never reached
public class ExternalIdSerializer : JsonConverter<ExternalId>
{
public override ExternalId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString() is null
? null
: new ExternalId(reader.GetString()!);
}

public override void Write(Utf8JsonWriter writer, ExternalId externalId, JsonSerializerOptions options)
{
writer.WriteStringValue(externalId.Id);
}
}
public class ExternalIdSerializer : JsonConverter<ExternalId>
{
public override ExternalId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString() is null
? null
: new ExternalId(reader.GetString()!);
}

public override void Write(Utf8JsonWriter writer, ExternalId externalId, JsonSerializerOptions options)
{
writer.WriteStringValue(externalId.Id);
}
}
And last, this is where I add my serializer
services
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;

var converters = options.JsonSerializerOptions.Converters;
converters.Add(new JsonStringEnumConverter());
converters.Add(new ExternalIdSerializer());
});
services
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;

var converters = options.JsonSerializerOptions.Converters;
converters.Add(new JsonStringEnumConverter());
converters.Add(new ExternalIdSerializer());
});
4 Replies
D.Mentia
D.Mentia•2y ago
Not sure I understand the intent, and idk the problem. But just in case you aren't aware and it might help you, you can natively serialize to a Dictionary<string,string> or <string,object>, if you have some arbitrary keys that you don't know ahead of time Newtonsoft also has an attribute to put all keys not defined on the model into such a dictionary
Doombox
Doombox•2y ago
that JSON Converter looks a lot like a System.Text.JSON one, do they share the same base class?
Arkobat
Arkobat•2y ago
Ohh, didn't realise they were called the same... I can see its using System.text 😦 So, I hav removed Newtonsoft from my project, and is now using Sytem.Text everywhere. However, I still see the same problem. I have updated my code examples to show what I do.
Doombox
Doombox•2y ago
IndentedJsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.General)
{
WriteIndented = true,
Converters = { new TypeJsonConverter() }
};
// ...
await JsonSerializer.DeserializeAsync<T>(filestream, IndentedJsonOptions);
IndentedJsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.General)
{
WriteIndented = true,
Converters = { new TypeJsonConverter() }
};
// ...
await JsonSerializer.DeserializeAsync<T>(filestream, IndentedJsonOptions);
is how I've done it I don't know how you'd do it with your services registration though