[CSHARP-3774] Parsing Enums as Strings is case-insensitive Created: 30/Jul/21  Updated: 28/Oct/23  Resolved: 13/Sep/21

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 2.13.2

Type: Bug Priority: Minor - P4
Reporter: Raphael Guntersweiler Assignee: Dmitry Lukyanov (Inactive)
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When enums are stored as string, they were parsed back case-sensitive until v2.12. Since that update, this behaviour was changed which causes issues when multiple enum values have different capitalizations.

Example:

public enum MyEnum {
    AnEnumValue,
    anenumvalue
}

In this example, Mongo will parse the string representation to the same Enum value.

In my opinion, this behavior should at least be configurable.

References in Code:

- src/MongoDB.Bson/Serialization/Serializers/EnumSerializer.cs (in v2.12, the parsing logic has changed by adding a boolean parameter to Enum.Parse())



 Comments   
Comment by Githook User [ 06/Oct/21 ]

Author:

{'name': 'Dmitry Lukyanov', 'email': 'dmitry.lukyanov@mongodb.com', 'username': 'DmitryLukyanov'}

Message: CSHARP-3774: Parsing Enums as Strings is case-insensitive. (#621)

CSHARP-3774: Parsing Enums as Strings is case-insensitive.
Branch: v2.13.x
https://github.com/mongodb/mongo-csharp-driver/commit/877a6e8d0b19357fa694a74212a44fe6cb64ee31

Comment by Githook User [ 13/Sep/21 ]

Author:

{'name': 'Dmitry Lukyanov', 'email': 'dmitry.lukyanov@mongodb.com', 'username': 'DmitryLukyanov'}

Message: CSHARP-3774: Parsing Enums as Strings is case-insensitive. (#621)

CSHARP-3774: Parsing Enums as Strings is case-insensitive.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/dc001c729c971ba0f4d6a6d316e1d7c9cecc3d09

Comment by Raphael Guntersweiler [ 02/Aug/21 ]

I do agree that having Enum values that differ in case should be a No-no, but sometimes you get forced into it. Your proposed change sounds like a good solution to the issue at hand.

We use an abstract storage implementation which uses separate classes on the DB and the Applications side. Our solution was to switch the "DB-side" implementation of the field from Enum to String and implement the conversion manually (using AutoMapper). If anyone happens to stumble across the same issue, I hope this serves as a starting point.

Comment by Robert Stam [ 02/Aug/21 ]

Thanks for reporting this. This is an unintended side effect of a change we made to be more forgiving when parsing input.

As a general rule we do want to be forgiving on input. For example, the `BooleanSerializer` accepts either "true" or "True" and either "false" or "False".

While it is probably not  a good idea to define enum values that differ only in case, we definitely should handle them properly when they are defined.

I don't think we want to make it configurable, it should just work. I think we can be forgiving and accurate at the same time.

Probably the following code change in `EnumSerializer.cs` should suffice:

// change"
private TEnum ConvertStringToEnum(string value) =>
    (TEnum)Enum.Parse(typeof(TEnum), value, true);
 
// to:
private TEnum ConvertStringToEnum(string value)
{
    // try case sensitive first, then fall back to case insensitive
    if (Enum.TryParse(typeof(TEnum), value, ignoreCase: false, out var result) || Enum.TryParse(typeof(TEnum), value, ignoreCase: true, out result))
    {
        return (TEnum)result;
    }    
 
    throw new ArgumentException($"Requested value '{value}' was not found.");
}

Alternatively we could revert the change to allow case insensitive parsing, but that doesn't seem necessary.

Comment by Dmitry Lukyanov (Inactive) [ 30/Jul/21 ]

Thanks raphael.guntersweiler@rwe.com for your report, we will check it and come back to you

Generated at Wed Feb 07 21:46:16 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.