Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion src/libraries/System.Text.Json/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
<value>'{0}' is invalid within a JSON string. The string should be correctly escaped.</value>
</data>
<data name="UnsupportedEnumIdentifier" xml:space="preserve">
<value>Enum type '{0}' uses unsupported identifier '{1}'. It must not be null, empty, or containing leading or trailing whitespace. Flags enums must additionally not contain commas.</value>
<value>Enum type '{0}' uses unsupported identifier '{1}'. It must not be null nor contain leading or trailing whitespace. Flags enums must additionally not be empty nor contain commas.</value>
</data>
<data name="InvalidEndOfJsonNonPrimitive" xml:space="preserve">
<value>'{0}' is an invalid token type for the end of the JSON payload. Expected either 'EndArray' or 'EndObject'.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,13 @@ private static string ResolveAndValidateJsonName(string name, JsonNamingPolicy?
name = namingPolicy.ConvertName(name);
}

if (string.IsNullOrEmpty(name) || char.IsWhiteSpace(name[0]) || char.IsWhiteSpace(name[name.Length - 1]) ||
(s_isFlagsEnum && name.Contains(',')))
if (name is null ||
(name.Length > 0 && (char.IsWhiteSpace(name[0]) || char.IsWhiteSpace(name[name.Length - 1]))) ||
(s_isFlagsEnum && (name.Length == 0 || name.Contains(','))))
Comment thread
eiriktsarpalis marked this conversation as resolved.
{
// Reject null or empty strings or strings with leading or trailing whitespace.
// In the case of flags additionally reject strings containing commas.
// Reject null strings or strings with leading or trailing whitespace.
// In the case of flags additionally reject empty strings or strings containing commas,
// both of which would introduce ambiguity in flag value parsing and formatting.
ThrowHelper.ThrowInvalidOperationException_UnsupportedEnumIdentifier(typeof(T), name);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,7 @@ public enum EnumWithInvalidMemberName1
Value
}

[Flags]
public enum EnumWithInvalidMemberName2
{
[JsonStringEnumMemberName("")]
Expand Down Expand Up @@ -1290,6 +1291,56 @@ public enum EnumWithInvalidMemberName6
Value
}

[Theory]
[InlineData(YesOrNoOrEmpty.Yes, "\"y\"")]
[InlineData(YesOrNoOrEmpty.No, "\"n\"")]
[InlineData(YesOrNoOrEmpty.Empty, "\"\"")]
public static void EnumWithEmptyStringMemberName_NonFlags_RoundtripsAsExpected(YesOrNoOrEmpty value, string expectedJson)
{
string json = JsonSerializer.Serialize(value, s_optionsWithStringEnumConverter);
Assert.Equal(expectedJson, json);
Assert.Equal(value, JsonSerializer.Deserialize<YesOrNoOrEmpty>(json, s_optionsWithStringEnumConverter));
}

public enum YesOrNoOrEmpty
{
[JsonStringEnumMemberName("y")]
Yes,

[JsonStringEnumMemberName("n")]
No,

[JsonStringEnumMemberName("")]
Comment thread
eiriktsarpalis marked this conversation as resolved.
Empty,
}

[Fact]
public static void EnumWithEmptyStringMemberName_Flags_Throws()
{
string expectedExceptionMessage = $"Enum type '{nameof(YesOrNoOrEmptyFlags)}' uses unsupported identifier ''.";

InvalidOperationException ex = Assert.Throws<InvalidOperationException>(
() => JsonSerializer.Serialize(YesOrNoOrEmptyFlags.Yes, s_optionsWithStringEnumConverter));
Assert.Contains(expectedExceptionMessage, ex.Message);

ex = Assert.Throws<InvalidOperationException>(
() => JsonSerializer.Deserialize<YesOrNoOrEmptyFlags>("\"y\"", s_optionsWithStringEnumConverter));
Assert.Contains(expectedExceptionMessage, ex.Message);
}

[Flags]
public enum YesOrNoOrEmptyFlags
{
[JsonStringEnumMemberName("y")]
Yes = 1,

[JsonStringEnumMemberName("n")]
No = 2,

[JsonStringEnumMemberName("")]
Empty = 4,
}

[Theory]
[InlineData("\"cAmElCaSe\"", EnumWithVaryingNamingPolicies.camelCase, JsonKnownNamingPolicy.SnakeCaseUpper)]
[InlineData("\"cAmElCaSe\"", EnumWithVaryingNamingPolicies.camelCase, JsonKnownNamingPolicy.SnakeCaseLower)]
Expand Down
Loading