Skip to content

Commit

Permalink
Fix factory converters used as attributes (dotnet/corefx#38740)
Browse files Browse the repository at this point in the history
* Fix factory converters used as attributes

Need to unpack the type specific converter when associating directly with a property.

Add default constructor to StringEnum converter.

* Move the factory unpack per feedback


Commit migrated from dotnet/corefx@c6c1890
  • Loading branch information
JeremyKuhne authored Jun 20, 2019
1 parent a56b0fb commit 183ba49
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ public virtual void Write(System.Text.Json.Utf8JsonWriter writer, T value, Syste
}
public sealed class JsonStringEnumConverter : System.Text.Json.Serialization.JsonConverterFactory
{
public JsonStringEnumConverter() { }
public JsonStringEnumConverter(System.Text.Json.JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) { }
public override bool CanConvert(System.Type type) { throw null; }
protected override System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type type) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ internal JsonConverter DetermineConverterForProperty(Type parentClassType, Type
converter = GetConverter(runtimePropertyType);
}

if (converter is JsonConverterFactory factory)
{
converter = factory.GetConverterInternal(runtimePropertyType);
}

return converter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ public sealed class JsonStringEnumConverter : JsonConverterFactory
private readonly JsonNamingPolicy _namingPolicy;
private readonly EnumConverterOptions _converterOptions;

/// <summary>
/// Constructor. Creates the <see cref="JsonStringEnumConverter"/> with the
/// default naming policy and allows integer values.
/// </summary>
public JsonStringEnumConverter()
: this(namingPolicy: null, allowIntegerValues: true)
{
// An empty constructor is needed for construction via attributes
}

/// <summary>
/// Constructor.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,36 @@ public class FileState
{
public FileAttributes Attributes { get; set; }
}

public class Week
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public DayOfWeek WorkStart { get; set; }
public DayOfWeek WorkEnd { get; set; }
[LowerCaseEnum]
public DayOfWeek WeekEnd { get; set; }
}

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false)]
private class LowerCaseEnumAttribute : JsonConverterAttribute
{
public LowerCaseEnumAttribute() { }

public override JsonConverter CreateConverter(Type typeToConvert)
=> new JsonStringEnumConverter(new ToLower());
}

[Fact]
public void ConvertEnumUsingAttributes()
{
Week week = new Week { WorkStart = DayOfWeek.Monday, WorkEnd = DayOfWeek.Friday, WeekEnd = DayOfWeek.Saturday };
string json = JsonSerializer.ToString(week);
Assert.Equal(@"{""WorkStart"":""Monday"",""WorkEnd"":5,""WeekEnd"":""saturday""}", json);

week = JsonSerializer.Parse<Week>(json);
Assert.Equal(DayOfWeek.Monday, week.WorkStart);
Assert.Equal(DayOfWeek.Friday, week.WorkEnd);
Assert.Equal(DayOfWeek.Saturday, week.WeekEnd);
}
}
}

0 comments on commit 183ba49

Please sign in to comment.