-
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
[API Proposal]: Add more extensive control over ignoring properties #55781
Comments
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsBackground and motivationIf I have this config:
And I return the following:
The result is:
This can cause confusion because the value of API Proposal// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.Text.Json.Serialization
{
/// <summary>
/// When specified on <see cref="JsonSerializerOptions.DefaultIgnoreCondition"/>,
/// determines when properties and fields across the type graph are ignored.
/// When specified on <see cref="JsonIgnoreAttribute.Condition"/>, controls whether
/// a property is ignored during serialization and deserialization. This option
/// overrides the setting on <see cref="JsonSerializerOptions.DefaultIgnoreCondition"/>.
/// </summary>
public enum JsonIgnoreCondition
{
/// <summary>
/// Property is never ignored during serialization or deserialization.
/// </summary>
Never = 0,
/// <summary>
/// Property is always ignored during serialization and deserialization.
/// </summary>
Always = 1,
/// <summary>
/// If the value is the default, the property is ignored during serialization.
/// This is applied to both reference and value-type properties and fields.
/// </summary>
WhenWritingDefault = 2,
/// <summary>
/// If the value is <see langword="null"/>, the property is ignored during serialization.
/// This is applied only to reference-type properties and fields.
/// </summary>
WhenWritingNull = 3,
/// <summary>
/// If the value is the default, the property is ignored during serialization.
/// This is applied to both reference and value-type properties and fields.
/// When using JsonStringEnumConverter enum properties will be included.
/// </summary>
WhenWritingDefaultExceptEnums = 4,
}
} API Usageservices.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefaultExceptEnums;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
}); RisksNo response
|
Exposing a separate setting only to exempt Related to #50294. It seems clear that What we could do instead is expose a mechanism for omitting properties at the converter level, for example: public class JsonConverter<T>
{
public virtual bool IgnoreProperty(T propertyValue, JsonSerializerOptions options) =>
// naive, partial implementation adopted for brevity
options.DefaultIgnoreCondition == JsonIgnoreCondition.WhenWritingDefault &&
EqualityComparer<T>.Default.Equals(propertyValue, default);
} and thus completely opt out JsonStringEnumConverter by default: public class StringEnumConverter<TEnum>
{
public override bool IgnoreProperty(TEnum _, JsonSerializerOptions options) => false;
} |
@eiriktsarpalis the proposal looks good to me, the only question to me would be whether the IgnoreProperty method is additive to or entirely overriding JsonSerializerOptions.JsonIgnoreCondition. Overriding is more powerful but I'd rather not come across too many 'constant false' converters that completely fail to respect any JsonIgnoreCondition. So it'd need some good guiding examples of how to do it right, either by looking up JsonIgnoreCondition in options or having specific converter options for it. |
Would it be an idea to make |
We might also want to consider #40395 for ignoring properties on the property level. |
I would love this capability, especially as outlined in #55781 (comment). In my case, I am trying to serialize public static void Main()
{
string json = JsonSerializer.Serialize(
new Test(),
new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, WriteIndented = true });
Console.WriteLine(json);
}
public class Test
{
[JsonPropertyName("foos")]
[JsonInclude]
[JsonConverter(typeof(EmptyOrNullListConverter<string>))]
public IList<string> Foos { get; } = new List<string>();
}
public class EmptyOrNullListConverter<T> : JsonConverter<IList<T>>
{
public override bool HandleNull => true;
public override IList<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => default;
public override void Write(Utf8JsonWriter writer, IList<T>? value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, value?.Count > 0 ? value : null, options);
} This gets me just about all the way there, but always writes |
I'm in need of a similar solution to what @nathan-alden-sr mentioned. As there seem to be multiple issues relating to this scenario, there is a definite need for the functionality built-in to STJ. It's not currently possible with converters (or anything else that I can find) today. I commented on a related issue #36785 (comment) that has more specifics for the scenario I'm encountering. |
@nathan-alden-sr I have posted a way to do this, maybe it works for you. You can check it our here: |
See my solution here: #593 (comment) |
I believe this could be addressed by #63686. We should make sure that this particular use case is covered and potential write a code sample demonstrating it. Regarding converter-level predicates (#55781 (comment)), I'm increasingly of the opinion that it should be addressed on the contract model instead. Closing in favor of #63686. |
Background and motivation
If I have this config:
And I return the following:
The result is:
This can cause confusion because the value of
DefaultEnum
is omitted because it's default is, but because it's converted as a string this reduces clarity.API Proposal
API Usage
Risks
No response
The text was updated successfully, but these errors were encountered: