I have an API developed in .NET6. Currently, all properties that are being returned as null, are being hidden via the below:
_ = services.AddControllers().AddJsonOptions(options => {
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; });
I require to ignore also values that are empty string. There I have implemented the below converter:
public class EmptyStringConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString()!;
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
if (!string.IsNullOrEmpty(value))
{
writer.WriteStringValue(value);
}
else
{
writer.WriteNullValue();
}
}
}
Added the converter to the AddJsonOptions
:
_ = services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new EmptyStringConverter());
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
The converter is working - changing empty string properties to null, but in the API response, these properties are visible, although I have set
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull.
I reviewed other articles stating to add the default attribute, but that means having to change all the properties of all the models, which is not feasible. Additionally, this also means that numbers with value 0, will be hidden, which is not something that I would want.
I require to use System.Text.Json rather than Newtonsoft.
Is there a way how I can achieve this please?
You can customize the JSON contract used by the DefaultJsonTypeInfoResolver
or derived type.
Below code changes each property of type string
to only serialize when not null and not empty.
This contract customization via property type inspection only occurs once per model type. It is the Func
applied to ShouldSerialize
that runs for each string
property value.
builder.Services
.AddControllers()
.AddJsonOptions(o => o.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver()
{
Modifiers =
{
jsonTypeInfo =>
{
foreach (var propertyInfo in jsonTypeInfo.Properties.Where(o => o.PropertyType == typeof(string)))
{
propertyInfo.ShouldSerialize = (parent, property) => !string.IsNullOrEmpty(property as string);
}
}
}
});