Skip to content
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

Added field support to JSON serializer #36986

Merged
merged 4 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ public JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults defaults) {
public System.Text.Encodings.Web.JavaScriptEncoder? Encoder { get { throw null; } set { } }
public bool IgnoreNullValues { get { throw null; } set { } }
public bool IgnoreReadOnlyProperties { get { throw null; } set { } }
public bool IgnoreReadOnlyFields { get { throw null; } set { } }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test using this option.

public bool IncludeFields { get { throw null; } set { } }
public int MaxDepth { get { throw null; } set { } }
public bool PropertyNameCaseInsensitive { get { throw null; } set { } }
public System.Text.Json.JsonNamingPolicy? PropertyNamingPolicy { get { throw null; } set { } }
Expand Down Expand Up @@ -479,7 +481,7 @@ public abstract partial class JsonConverter
internal JsonConverter() { }
public abstract bool CanConvert(System.Type typeToConvert);
}
[System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Enum | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple=false)]
[System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple=false)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test using the attribute on a field, along with JsonIgnoreAttribute, JsonIncludeAttribute, JsonExtensionDataAttribute & JsonPropertyName.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some new tests, but not finished yet. For naming they already exist.

public partial class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute
{
protected JsonConverterAttribute() { }
Expand All @@ -506,23 +508,23 @@ public sealed partial class JsonConstructorAttribute : System.Text.Json.Serializ
{
public JsonConstructorAttribute() { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false)]
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple=false)]
public sealed partial class JsonExtensionDataAttribute : System.Text.Json.Serialization.JsonAttribute
{
public JsonExtensionDataAttribute() { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false)]
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple=false)]
public sealed partial class JsonIgnoreAttribute : System.Text.Json.Serialization.JsonAttribute
{
public JsonIgnoreAttribute() { }
public System.Text.Json.Serialization.JsonIgnoreCondition Condition { get { throw null; } set { } }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple = false)]
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)]
public sealed partial class JsonIncludeAttribute : System.Text.Json.Serialization.JsonAttribute
{
public JsonIncludeAttribute() { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false)]
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple=false)]
public sealed partial class JsonPropertyNameAttribute : System.Text.Json.Serialization.JsonAttribute
{
public JsonPropertyNameAttribute(string name) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
namespace System.Text.Json.Serialization
{
/// <summary>
/// When placed on a property or type, specifies the converter type to use.
/// When placed on a property, field, or type, specifies the converter type to use.
/// </summary>
/// <remarks>
/// The specified converter type must derive from <see cref="JsonConverter"/>.
/// When placed on a property, the specified converter will always be used.
/// When placed on a property or field, the specified converter will always be used.
/// When placed on a type, the specified converter will be used unless a compatible converter is added to
/// <see cref="JsonSerializerOptions.Converters"/> or there is another <see cref="JsonConverterAttribute"/> on a property
/// <see cref="JsonSerializerOptions.Converters"/> or there is another <see cref="JsonConverterAttribute"/> on a member
/// of the same type.
/// </remarks>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Struct, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class JsonConverterAttribute : JsonAttribute
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
namespace System.Text.Json.Serialization
{
/// <summary>
/// When placed on a property of type <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"/>, any
/// properties that do not have a matching member are added to that Dictionary during deserialization and written during serialization.
/// When placed on a property or field of type <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"/>, any
/// properties that do not have a matching property or field are added to that Dictionary during deserialization and written during serialization.
/// </summary>
/// <remarks>
/// The TKey value must be <see cref="string"/> and TValue must be <see cref="JsonElement"/> or <see cref="object"/>.
///
/// During deserializing, when using <see cref="object"/> a "null" JSON value is treated as a <c>null</c> object reference, and when using
/// <see cref="JsonElement"/> a "null" is treated as a JsonElement with <see cref="JsonElement.ValueKind"/> set to <see cref="JsonValueKind.Null"/>.
///
/// During serializing, the name of the extension data property is not included in the JSON;
/// During serializing, the name of the extension data member is not included in the JSON;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

member

change to property or field here and below.

/// the data contained within the extension data is serialized as properties of the JSON object.
///
/// If there is more than one extension property on a type, or it the property is not of the correct type,
/// If there is more than one extension member on a type, or it the member is not of the correct type,
/// an <see cref="InvalidOperationException"/> is thrown during the first serialization or deserialization of that type.
/// </remarks>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public sealed class JsonExtensionDataAttribute : JsonAttribute
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
namespace System.Text.Json.Serialization
{
/// <summary>
/// Prevents a property from being serialized or deserialized.
/// Prevents a property or field from being serialized or deserialized.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public sealed class JsonIgnoreAttribute : JsonAttribute
{
/// <summary>
/// Specifies the condition that must be met before a property will be ignored.
/// Specifies the condition that must be met before a property or field will be ignored.
/// </summary>
/// <remarks>The default value is <see cref="JsonIgnoreCondition.Always"/>.</remarks>
public JsonIgnoreCondition Condition { get; set; } = JsonIgnoreCondition.Always;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace System.Text.Json.Serialization
/// <remarks>
/// When applied to a property, indicates that non-public getters and setters can be used for serialization and deserialization.
/// </remarks>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)]
public sealed class JsonIncludeAttribute : JsonAttribute
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace System.Text.Json.Serialization
/// Specifies the property name that is present in the JSON when serializing and deserializing.
/// This overrides any naming policy specified by <see cref="JsonNamingPolicy"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public sealed class JsonPropertyNameAttribute : JsonAttribute
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,26 @@ internal sealed partial class JsonClassInfo
// Use an array (instead of List<T>) for highest performance.
private volatile PropertyRef[]? _propertyRefsSorted;

public static JsonPropertyInfo AddProperty(PropertyInfo propertyInfo, Type parentClassType, JsonSerializerOptions options)
public static JsonPropertyInfo AddProperty(MemberInfo memberInfo, Type memberType, Type parentClassType, JsonSerializerOptions options)
{
JsonIgnoreCondition? ignoreCondition = JsonPropertyInfo.GetAttribute<JsonIgnoreAttribute>(propertyInfo)?.Condition;
JsonIgnoreCondition? ignoreCondition = JsonPropertyInfo.GetAttribute<JsonIgnoreAttribute>(memberInfo)?.Condition;

if (ignoreCondition == JsonIgnoreCondition.Always)
{
return JsonPropertyInfo.CreateIgnoredPropertyPlaceholder(propertyInfo, options);
return JsonPropertyInfo.CreateIgnoredPropertyPlaceholder(memberInfo, options);
}

Type propertyType = propertyInfo.PropertyType;

JsonConverter converter = GetConverter(
propertyType,
memberType,
parentClassType,
propertyInfo,
memberInfo,
out Type runtimeType,
options);

return CreateProperty(
declaredPropertyType: propertyType,
declaredPropertyType: memberType,
runtimePropertyType: runtimeType,
propertyInfo,
memberInfo,
parentClassType,
converter,
options,
Expand All @@ -84,7 +82,7 @@ public static JsonPropertyInfo AddProperty(PropertyInfo propertyInfo, Type paren
internal static JsonPropertyInfo CreateProperty(
Type declaredPropertyType,
Type? runtimePropertyType,
PropertyInfo? propertyInfo,
MemberInfo? memberInfo,
Type parentClassType,
JsonConverter converter,
JsonSerializerOptions options,
Expand All @@ -98,7 +96,7 @@ internal static JsonPropertyInfo CreateProperty(
declaredPropertyType,
runtimePropertyType,
runtimeClassType: converter.ClassType,
propertyInfo,
memberInfo,
converter,
ignoreCondition,
options);
Expand All @@ -119,7 +117,7 @@ internal static JsonPropertyInfo CreatePropertyInfoForClassInfo(
JsonPropertyInfo jsonPropertyInfo = CreateProperty(
declaredPropertyType: declaredPropertyType,
runtimePropertyType: runtimePropertyType,
propertyInfo: null, // Not a real property so this is null.
memberInfo: null, // Not a real property so this is null.
parentClassType: JsonClassInfo.ObjectType, // a dummy value (not used)
converter: converter,
options);
Expand Down
Loading