Bug #108970 MySqlConnectionStringBuilder ContainsKey method gives wrong result
Submitted: 2 Nov 2022 13:30 Modified: 6 Jun 2023 16:28
Reporter: Eric Finch Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version: OS:Windows
Assigned to: CPU Architecture:Any

[2 Nov 2022 13:30] Eric Finch
Description:
The MySqlConnectionStringBuilder ContainsKey method returns true for keys that have not been set.  You can even inspect the Keys property to see what keys have actually been set. ContainsKey does not return true for any string, only ones that would be a valid setting.  I have tested this with "AllowUserVariables" and "UseAffectedRows", which always return true, even when they are not present in the Keys collection.

    <PackageReference Include="MySql.Data" Version="8.0.31" />

How to repeat:
1. Create a new MySqlConnectionStringBuilder with a connection string that does not contain "AllowUserVariables".
2. Call ContainsKey("AllowUserVariables"), which will return true, when it should return false.
3. Inspect Keys collection and see that "AllowUserVariables" is not present in the list.
4. Set "AllowUserVariables" in the MySqlConnectionStringBuilder.
5. See that "AllowUserVariables" now shows up in the Keys collection.

Suggested fix:
ContainsKey should return false for properties that have not been set through the connection string, Property, or indexer.  Basically, ContainsKey should return false, unless the key shows in the Keys collection.
[10 Nov 2022 12:45] MySQL Verification Team
Hello Eric Finch,

Thank you for the bug report.
Could you please provide repeatable test case (sample project, etc. - please make it as private if you prefer) to confirm this issue at our end?

Regards,
Ashwini Patil
[10 Nov 2022 13:29] Eric Finch
Example code:
            const string ConnectionKey = "AllowUserVariables";
            var builder = new localMySqlClient.MySqlConnectionStringBuilder();
            if (builder.Keys.Cast<string>().Any(k => string.Equals(k, ConnectionKey, System.StringComparison.OrdinalIgnoreCase)))
            {
                // this will be false
                throw new System.Exception("Did not expect key in Keys collection");
            }
            if (builder.ContainsKey(ConnectionKey))
            {
                // this will be true
                throw new System.Exception("Did not expect to find key with ContainsKey.");
            }
[15 Nov 2022 7:28] MySQL Verification Team
Hello Eric Finch,

Thank you for the details.
Verified as described.

Regards,
Ashwini Patil
[6 Jun 2023 16:28] Reggie Burnett
This is not a bug.  ContainsKey does not represent if a key name was physically given but if the connection string has a value for the given key.  Please see the test code below that uses SqlClient.  

SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder();
var timeout = sb["Timeout"];
var hasKey = sb.ContainsKey("Timeout");
Console.WriteLine("timeout = " + timeout);
Console.WriteLine("Contains key = " + hasKey);

The output of this code will be the following:

timeout = 15
Contains key = True