From 74c64aecb485ef65eb8e33b1d921a5d7a3478984 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Mon, 3 Jan 2022 11:18:38 +0000 Subject: [PATCH] 1.1.0 --- CHANGELOG.md | 4 ++ Directory.Build.props | 2 +- Generate-ReleaseNotes.cmd | 7 ++ GitHubReleaseNotes.txt | 3 - README.md | 28 +++++++- System.Text.Json.EnumExtensions Solution.sln | 6 +- examples/ConsoleApp/Program.cs | 67 ++++++++++--------- ...nValueConverterEnumWithAttributeSupport.cs | 10 +-- ...StringEnumConverterWithAttributeSupport.cs | 16 +++-- 9 files changed, 92 insertions(+), 51 deletions(-) create mode 100644 Generate-ReleaseNotes.cmd delete mode 100644 GitHubReleaseNotes.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 624a3b6..15bacea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 (03 January 2022) +- [#7](https://github.com/StefH/System.Text.Json.EnumExtensions/pull/7) - Added parameterless constructor for JsonStringEnumConverterWithAttributeSupport [enhancement] contributed by [hughesjs](https://github.com/hughesjs) +- [#6](https://github.com/StefH/System.Text.Json.EnumExtensions/issues/6) - Make Compatible with `JsonConverterAttribute` + # 1.0.1 (20 March 2021) - [#1](https://github.com/StefH/System.Text.Json.EnumExtensions/pull/1) - Add dotnet command copyable example [documentation] contributed by [lol768](https://github.com/lol768) - [#3](https://github.com/StefH/System.Text.Json.EnumExtensions/pull/3) - Add netstandard2.1 and net5.0 targets [enhancement] contributed by [StefH](https://github.com/StefH) diff --git a/Directory.Build.props b/Directory.Build.props index 57cd8c2..6322d6c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ - 1.0.1 + 1.1.0 diff --git a/Generate-ReleaseNotes.cmd b/Generate-ReleaseNotes.cmd new file mode 100644 index 0000000..e672838 --- /dev/null +++ b/Generate-ReleaseNotes.cmd @@ -0,0 +1,7 @@ +rem https://github.com/StefH/GitHubReleaseNotes + +SET version=1.1.0 + +GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version %version% + +rem GitHubReleaseNotes --output PackageReleaseNotes.txt --skip-empty-releases --exclude-labels question invalid doc --template PackageReleaseNotes.template --version %version% \ No newline at end of file diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt deleted file mode 100644 index 5c67ac5..0000000 --- a/GitHubReleaseNotes.txt +++ /dev/null @@ -1,3 +0,0 @@ -https://github.com/StefH/GitHubReleaseNotes - -GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.1 diff --git a/README.md b/README.md index 31d6bdc..48d2468 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ If you use the `dotnet` command: `dotnet add package EnumExtensions.System.Text.Json` -## Usage Example - EnumMember +## Option 1: Usage Example - EnumMember ### Define Enum and add attributes Define an Enum and annotate the Enum fields with the [EnumMemberAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.enummemberattribute?view=netstandard-2.0): @@ -62,6 +62,32 @@ var json = "{\"WeatherType\":\"Zonnig\"}"; var weatherForecastDeserialized = JsonSerializer.Deserialize(json, options); ``` + +## Option 2: Usage Example - EnumMember +It's also possible to annotate the Enum with a `[JsonConverter]` so that you don't need to manually registerd the `JsonStringEnumConverterWithAttributeSupport` to the Converters via the JsonSerializerOptions. + +### Define Enum and add attributes +Define an Enum +- add the `[JsonConverter(typeof(JsonStringEnumConverterWithAttributeSupport))]` to the Enum +- annotate the Enum fields with the [EnumMemberAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.enummemberattribute?view=netstandard-2.0): +``` c# +[JsonConverter(typeof(JsonStringEnumConverterWithAttributeSupport))] +enum WeatherType +{ + [EnumMember(Value = "Zonnig")] + Sunny, + + [EnumMember(Value = "Helder")] + Clear +} +``` + +### Serializing and Deserialize an object +This works the same as using Option 1. + +Note that only Enum values which are annotated with `EnumMember` are supported. + + ## Usage Example - Display and Description It's also possible to annotate Enum fields with these attributes: - [DisplayAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.displayattribute?view=netframework-4.8) diff --git a/System.Text.Json.EnumExtensions Solution.sln b/System.Text.Json.EnumExtensions Solution.sln index 0e6c52a..aa8a0ce 100644 --- a/System.Text.Json.EnumExtensions Solution.sln +++ b/System.Text.Json.EnumExtensions Solution.sln @@ -1,14 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29409.12 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.31911.260 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{231E7EC1-B4A9-4DB1-B21C-8D8ED136A1DC}" ProjectSection(SolutionItems) = preProject azure-pipelines.yml = azure-pipelines.yml CHANGELOG.md = CHANGELOG.md Directory.Build.props = Directory.Build.props - GitHubReleaseNotes.txt = GitHubReleaseNotes.txt + Generate-ReleaseNotes.cmd = Generate-ReleaseNotes.cmd README.md = README.md EndProjectSection EndProject diff --git a/examples/ConsoleApp/Program.cs b/examples/ConsoleApp/Program.cs index 0f48061..6fd9630 100644 --- a/examples/ConsoleApp/Program.cs +++ b/examples/ConsoleApp/Program.cs @@ -35,31 +35,33 @@ class WeatherForecast public WeatherType WeatherTypeInteger { get; set; } } + /// + /// Only `EnumMember` is supported when using Parameterless constructor + /// [JsonConverter(typeof(JsonStringEnumConverterWithAttributeSupport))] enum SpaceWeatherType { - Unknown, + Unknown = 0, - [EnumMember(Value = "Solar Flare")] + [EnumMember(Value = "Solar_Flare")] SolarFlare, - [Display(Name = "CME")] + [EnumMember(Value = "CME")] CoronalMassEjection, - [Description("Heavy Bombardment")] HeavyBombardment, - [Description("Empty Void")] + [EnumMember(Value = "Empty_Void")] EmptyVoid } - + class SpaceWeatherForecast { - public SpaceWeatherType WeatherTypeEnumMember { get; set; } + public SpaceWeatherType WeatherTypeEnumMember1 { get; set; } - public SpaceWeatherType WeatherTypeDisplay { get; set; } + public SpaceWeatherType WeatherTypeEnumMember2 { get; set; } - public SpaceWeatherType WeatherTypeDescription { get; set; } + public SpaceWeatherType WeatherTypeEnumMember3 { get; set; } public SpaceWeatherType WeatherTypeInteger { get; set; } } @@ -69,40 +71,41 @@ class Program static void Main(string[] args) { DemoWithJsonOptions(); + Console.WriteLine(new string('-', 120)); DemoWithConverterAttribute(); } private static void DemoWithConverterAttribute() { - var weatherForecast = new SpaceWeatherForecast() - { - WeatherTypeEnumMember = SpaceWeatherType.SolarFlare, - WeatherTypeDisplay = SpaceWeatherType.CoronalMassEjection, - WeatherTypeDescription = SpaceWeatherType.HeavyBombardment, - WeatherTypeInteger = SpaceWeatherType.EmptyVoid - }; - - var weatherForecastSerialized = JsonSerializer.Serialize(weatherForecast); - Console.WriteLine($"WeatherForecast:\r\n{weatherForecastSerialized}"); + var spaceWeatherForecast = new SpaceWeatherForecast + { + WeatherTypeEnumMember1 = SpaceWeatherType.SolarFlare, + WeatherTypeEnumMember2 = SpaceWeatherType.CoronalMassEjection, + WeatherTypeEnumMember3 = SpaceWeatherType.HeavyBombardment, + WeatherTypeInteger = SpaceWeatherType.EmptyVoid + }; + + var spaceWeatherForecastSerialized = JsonSerializer.Serialize(spaceWeatherForecast); + Console.WriteLine($"SpaceWeatherForecast:\r\n{spaceWeatherForecastSerialized}"); Console.WriteLine(); - var json = "{\"WeatherTypeEnumMember\":\"Solar Flare\",\"WeatherTypeDisplay\":\"CME\",\"WeatherTypeDescription\":\"Heavy Bombardment\",\"WeatherTypeInteger\":4}"; - var weatherForecastDeserialized = JsonSerializer.Deserialize(json); - Console.WriteLine(weatherForecastDeserialized.WeatherTypeEnumMember); - Console.WriteLine(weatherForecastDeserialized.WeatherTypeDisplay); - Console.WriteLine(weatherForecastDeserialized.WeatherTypeDescription); - Console.WriteLine(weatherForecastDeserialized.WeatherTypeInteger); + var json = "{\"WeatherTypeEnumMember1\":\"Solar_Flare\",\"WeatherTypeEnumMember2\":\"CME\",\"WeatherTypeEnumMember3\":\"HeavyBombardment\",\"WeatherTypeInteger\":4}"; + var spaceWeatherForecastDeserialized = JsonSerializer.Deserialize(json)!; + Console.WriteLine(spaceWeatherForecastDeserialized.WeatherTypeEnumMember1); + Console.WriteLine(spaceWeatherForecastDeserialized.WeatherTypeEnumMember2); + Console.WriteLine(spaceWeatherForecastDeserialized.WeatherTypeEnumMember3); + Console.WriteLine(spaceWeatherForecastDeserialized.WeatherTypeInteger); } private static void DemoWithJsonOptions() { var weatherForecast = new WeatherForecast - { - WeatherTypeEnumMember = WeatherType.Sunny, - WeatherTypeDisplay = WeatherType.Clear, - WeatherTypeDescription = WeatherType.Cloudy, - WeatherTypeInteger = WeatherType.Snow - }; + { + WeatherTypeEnumMember = WeatherType.Sunny, + WeatherTypeDisplay = WeatherType.Clear, + WeatherTypeDescription = WeatherType.Cloudy, + WeatherTypeInteger = WeatherType.Snow + }; var options = new JsonSerializerOptions(); options.Converters.Add(new JsonStringEnumConverterWithAttributeSupport(null, true, true, true, true)); @@ -112,7 +115,7 @@ private static void DemoWithJsonOptions() Console.WriteLine(); var json = "{\"WeatherTypeEnumMember\":\"Zonnig\",\"WeatherTypeDisplay\":\"Helder\",\"WeatherTypeDescription\":\"Bewolkt\",\"WeatherTypeInteger\":4}"; - var weatherForecastDeserialized = JsonSerializer.Deserialize(json, options); + var weatherForecastDeserialized = JsonSerializer.Deserialize(json, options)!; Console.WriteLine(weatherForecastDeserialized.WeatherTypeEnumMember); Console.WriteLine(weatherForecastDeserialized.WeatherTypeDisplay); Console.WriteLine(weatherForecastDeserialized.WeatherTypeDescription); diff --git a/src/System.Text.Json.EnumExtensions/Serialization/Converters/JsonValueConverterEnumWithAttributeSupport.cs b/src/System.Text.Json.EnumExtensions/Serialization/Converters/JsonValueConverterEnumWithAttributeSupport.cs index 4b6cf5c..08d9d0e 100644 --- a/src/System.Text.Json.EnumExtensions/Serialization/Converters/JsonValueConverterEnumWithAttributeSupport.cs +++ b/src/System.Text.Json.EnumExtensions/Serialization/Converters/JsonValueConverterEnumWithAttributeSupport.cs @@ -17,10 +17,10 @@ namespace System.Text.Json.Serialization.Converters internal class JsonValueConverterEnumWithAttributeSupport : JsonConverter where T : struct, Enum { - private static readonly TypeCode s_enumTypeCode = Type.GetTypeCode(typeof(T)); + private static readonly TypeCode EnumTypeCode = Type.GetTypeCode(typeof(T)); // Odd type codes are conveniently signed types (for enum backing types). - private static readonly string s_negativeSign = ((int)s_enumTypeCode % 2) == 0 ? null : NumberFormatInfo.CurrentInfo.NegativeSign; + private static readonly string NegativeSign = (int)EnumTypeCode % 2 == 0 ? null : NumberFormatInfo.CurrentInfo.NegativeSign; private readonly EnumConverterOptions _converterOptions; private readonly JsonNamingPolicy _namingPolicy; @@ -77,7 +77,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial throw new JsonException(); } - switch (s_enumTypeCode) + switch (EnumTypeCode) { // Switch cases ordered by expected frequency case TypeCode.Int32: @@ -150,7 +150,7 @@ private static bool IsValidIdentifier(string value) // preceded by a negative sign. Identifiers have to start with a letter // so we'll just pick the first valid one and check for a negative sign // if needed. - return value[0] >= 'A' && (s_negativeSign == null || !value.StartsWith(s_negativeSign)); + return value[0] >= 'A' && (NegativeSign == null || !value.StartsWith(NegativeSign)); } private bool TryParseFromAttribute(string value, out T resolvedEnumValue) @@ -243,7 +243,7 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions throw new JsonException(); } - switch (s_enumTypeCode) + switch (EnumTypeCode) { case TypeCode.Int32: writer.WriteNumberValue(Unsafe.As(ref value)); diff --git a/src/System.Text.Json.EnumExtensions/Serialization/JsonStringEnumConverterWithAttributeSupport.cs b/src/System.Text.Json.EnumExtensions/Serialization/JsonStringEnumConverterWithAttributeSupport.cs index 8f4145d..7b7133a 100644 --- a/src/System.Text.Json.EnumExtensions/Serialization/JsonStringEnumConverterWithAttributeSupport.cs +++ b/src/System.Text.Json.EnumExtensions/Serialization/JsonStringEnumConverterWithAttributeSupport.cs @@ -1,6 +1,6 @@ -using JetBrains.Annotations; -using System.Reflection; +using System.Reflection; using System.Text.Json.Serialization.Converters; +using JetBrains.Annotations; // ReSharper disable once CheckNamespace namespace System.Text.Json.Serialization @@ -21,8 +21,12 @@ public class JsonStringEnumConverterWithAttributeSupport : JsonConverterFactory /// Parse using , default is . /// Parse using , default is . /// Parse using , default is . - public JsonStringEnumConverterWithAttributeSupport([CanBeNull] JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true, - bool parseEnumMemberAttribute = true, bool parseDisplayAttribute = false, bool parseDescriptionAttribute = false) + public JsonStringEnumConverterWithAttributeSupport( + [CanBeNull] JsonNamingPolicy namingPolicy = null, + bool allowIntegerValues = true, + bool parseEnumMemberAttribute = true, + bool parseDisplayAttribute = false, + bool parseDescriptionAttribute = false) { _namingPolicy = namingPolicy; _converterOptions = allowIntegerValues @@ -44,7 +48,7 @@ public JsonStringEnumConverterWithAttributeSupport([CanBeNull] JsonNamingPolicy _converterOptions |= EnumConverterOptions.ParseDescriptionAttribute; } } - + /// /// Parameterless constructor. /// @@ -72,4 +76,4 @@ public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializer return converter; } } -} +} \ No newline at end of file