Bug #75172 KeyNotFoundException from MySqlConnectionStringBuilder.GetConnectionString
Submitted: 11 Dec 2014 8:56 Modified: 12 Nov 2015 23:01
Reporter: Andrii Nikitin Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / NET Severity:S3 (Non-critical)
Version:6.9.4 OS:Any
Assigned to: CPU Architecture:Any

[11 Dec 2014 8:56] Andrii Nikitin
Description:
Upon certain actions following stack trace may appear (for readability namespace prefixes were stripped):

.Generic.KeyNotFoundException: The given key was not present in the dictionary. 
.Generic.Dictionary`2.get_Item(TKey key) 
.MySqlClient.MySqlConnectionStringBuilder.<.cctor>b__7(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender) 
.MySqlClient.MySqlConnectionStringBuilder.get_Item(String keyword) 
.MySqlClient.MySqlConnectionStringBuilder.GetConnectionString(Boolean includePass) 
.MySqlClient.MySqlConnection.get_ConnectionString() 
.Entity.Infrastructure.Interception.DbConnectionDispatcher.<GetConnectionString>b__12(DbConnection t, DbConnectionInterceptionContext`1 c) 
.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
.Entity.Infrastructure.Interception.DbConnectionDispatcher.GetConnectionString(DbConnection connection, DbInterceptionContext interceptionContext) 
.Entity.Internal.InternalConnection.GetStoreConnectionString(DbConnection connection) 
.Entity.Internal.InternalConnection.OnConnectionInitialized() 
.Entity.Internal.EagerInternalConnection..ctor(DbContext context, DbConnection existingConnection, Boolean connectionOwned) 
.Entity.DbContext..ctor(DbConnection existingConnection, Boolean contextOwnsConnection) 
.Entity.Migrations.History.HistoryContext..ctor(DbConnection existingConnection, String defaultSchema) 
.Entity.MySqlEFConfiguration.<.ctor>b__1(DbConnection existingConnection, String defaultSchema) 
.Entity.Migrations.History.HistoryRepository.CreateContext(DbConnection connection, String schema) 
.Entity.Migrations.History.HistoryRepository.<GetUpgradeOperations>d__16.MoveNext() 
.Enumerable.Any[TSource](IEnumerable`1 source) 
.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration) 
.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b() 
.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) 
.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) 
.Entity.Migrations.DbMigrator.Update(String targetMigration) 
.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 
.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run() 
.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 
.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force) 
.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0() 
.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)

Looking at source code of C/NET, it was identified that following parameter in connection string brings the problem:
Integrated Security=false 

In particular, following lines in MySqlConnectionStringBuilder.cs have bug:

     options.Add(new MySqlConnectionStringOption("integratedsecurity", "integrated security", typeof(bool), false, false,
        delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
        {
          if (!MySql.Data.Common.Platform.IsWindows())
            throw new MySqlException("IntegratedSecurity is supported on Windows only");

          msb.SetValue("Integrated Security", value);
        },
        delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
        {
          object val = msb.values["Integrated Security"];
          return (bool)val;
        }

The problem here is that msb.values is case sensitive, so setter and getter must use lower case "integrated security" instead of mixed case "Integrated Security".

How to repeat:
Actual steps may be very complex, so bug was verified just looking at stack trace and source code.

Customer confirmed that removing "Integrated Security = false" from connection string solved the problem.

Use that as Workaround.

Suggested fix:
use lower case in msb.SetValue and msb.values above, 
or
use StringComparer.OrdinalIgnoreCase while creating this dictionary:

  public sealed partial class MySqlConnectionStringBuilder 
  {
    internal Dictionary<string, object> values = new Dictionary<string, object>();
[12 Nov 2015 17:51] Gabriela Martinez Sanchez
Updating version due that we don't have 5.9.4 in support currently.
[12 Nov 2015 23:01] Gabriela Martinez Sanchez
Tested with
Connector/Net 6.9.8 and server 5.7.9 Commercial Advanced in Windows 8.1.

Used

Integrated Security = yes
Integrated Security = true 
Integrated Security = false

and integrated security (lower cases) with the same values in connection string. And all worked fine.

Although using Integrated Security = sspi throws an exception.

Could you please try with this same version (6.9.8) and report if there is any issue?

Thanks in advance.