Skip to content

Commit c8895e6

Browse files
Deserialize Unknown Enum Values
1 parent 9dc4f2b commit c8895e6

File tree

5 files changed

+84
-3
lines changed

5 files changed

+84
-3
lines changed

src/MudBlazorPages/AppSettings.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,27 @@
22

33
namespace MudBlazorPages;
44

5+
public enum ExampleEnum
6+
{
7+
None = 0,
8+
FirstValue = 1,
9+
}
10+
511
public class AppSettings
612
{
713
[JsonPropertyName("stringValue")]
814
public string? StringValue { get; set; }
915

1016
[JsonPropertyName("intValue")]
1117
public int IntValue { get; set; }
18+
19+
[JsonPropertyName("enumValue")]
20+
public ExampleEnum EnumValue { get; set; }
21+
22+
/// <summary>
23+
/// This property simply demonstrates that non-existent enum values will not cause an exception during deserialization.
24+
/// See <see cref="Util.UnknownEnumConverter"/>
25+
/// </summary>
26+
[JsonPropertyName("nonexistentEnumValue")]
27+
public ExampleEnum NonexistentEnumValue { get; set; }
1228
}

src/MudBlazorPages/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
using Microsoft.AspNetCore.Components.Web;
44
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
55
using MudBlazor.Services;
6-
using System.Text.Json.Serialization;
76
using MudBlazorPages;
7+
using MudBlazorPages.Util;
88

99
var builder = WebAssemblyHostBuilder.CreateDefault(args);
1010
builder.RootComponents.Add<App>("#app");
@@ -13,7 +13,7 @@
1313
var http = new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) };
1414
builder.Services.AddScoped(sp => http);
1515

16-
var appSettings = await http.GetFromJsonAsync<AppSettings>("appsettings.json", new System.Text.Json.JsonSerializerOptions() { Converters = { new JsonStringEnumConverter() } });
16+
var appSettings = await http.GetFromJsonAsync<AppSettings>("appsettings.json", new System.Text.Json.JsonSerializerOptions() { Converters = { new UnknownEnumConverter() } });
1717
builder.Services.AddSingleton(appSettings ?? new());
1818

1919
builder.Services.AddMudServices();
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
3+
4+
namespace MudBlazorPages.Util.Generic;
5+
6+
/// <summary>
7+
/// Copied from https://gaevoy.com/2023/09/26/dotnet-serialization-unknown-enums-handling-api.html
8+
/// </summary>
9+
/// <typeparam name="T">An <see cref="Enum"/> type</typeparam>
10+
public class UnknownEnumConverter<T> : JsonConverter<T> where T : struct, Enum
11+
{
12+
private readonly JsonConverter<T> _underlying;
13+
14+
public UnknownEnumConverter(JsonConverter<T> underlying)
15+
=> _underlying = underlying;
16+
17+
public override T Read(ref Utf8JsonReader reader, Type enumType, JsonSerializerOptions options)
18+
{
19+
try
20+
{
21+
return _underlying.Read(ref reader, enumType, options);
22+
}
23+
catch (JsonException) when (enumType.IsEnum)
24+
{
25+
return default;
26+
}
27+
}
28+
29+
public override bool CanConvert(Type typeToConvert)
30+
=> _underlying.CanConvert(typeToConvert);
31+
32+
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
33+
=> _underlying.Write(writer, value, options);
34+
35+
public override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
36+
=> _underlying.ReadAsPropertyName(ref reader, typeToConvert, options);
37+
38+
public override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
39+
=> _underlying.WriteAsPropertyName(writer, value, options);
40+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
3+
using MudBlazorPages.Util.Generic;
4+
5+
namespace MudBlazorPages.Util;
6+
7+
/// <summary>
8+
/// Copied from https://gaevoy.com/2023/09/26/dotnet-serialization-unknown-enums-handling-api.html
9+
/// </summary>
10+
public class UnknownEnumConverter : JsonConverterFactory
11+
{
12+
private readonly JsonStringEnumConverter _underlying = new();
13+
14+
public sealed override bool CanConvert(Type enumType)
15+
=> _underlying.CanConvert(enumType);
16+
17+
public sealed override JsonConverter CreateConverter(Type enumType, JsonSerializerOptions options)
18+
{
19+
var underlyingConverter = _underlying.CreateConverter(enumType, options);
20+
var converterType = typeof(UnknownEnumConverter<>).MakeGenericType(enumType);
21+
return (JsonConverter)Activator.CreateInstance(converterType, underlyingConverter);
22+
}
23+
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
{
22
"stringValue": "Example String Value",
3-
"intValue": 4
3+
"intValue": 4,
4+
"enumValue": "FirstValue",
5+
"nonexistentEnumValue": "TheNonexistentEnumValue"
46
}

0 commit comments

Comments
 (0)