An System.Collections.Generic.KeyNotFoundException "The given key was not present in the dictionary" can be the result of using a too old MySQL Connector/NET version in your ASP.NET web application. A KeyNotFoundException is thrown when an operation attempts to retrieve an element from a collection using a key that does not exist in that collection. An unsupported character set like utf8mb4 can be such a key, if your Connector/NET doesn't support this character set. Luckily there is an easy workaround for this.

MySQL (Oracle) Connector/NET versions prior to 6.0.8, 6.1.6, 6.2.5, 6.3.6 lack a mapping for UTF8MB4 as charset. Connecting to a MySQL database and querying a table that has been created with CHARSET=utf8mb4 results in a .NET exception:

Exception Details: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at MySql.Data.MySqlClient.CharSetMap.GetCharacterSet(DBVersion version, String CharSetName) at MySql.Data.MySqlClient.CharSetMap.GetEncoding(DBVersion version, String CharSetName) at MySql.Data.MySqlClient.Driver.Configure(MySqlConnection connection) at MySql.Data.MySqlClient.MySqlConnection.Open() at ASP.mysql_data_aspx.MySQLConn()

A more extended exception is:

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at MySql.Data.MySqlClient.CharSetMap.GetCharacterSet(DBVersion version, String CharSetName) at MySql.Data.MySqlClient.MySqlField.SetFieldEncoding() at MySql.Data.MySqlClient.NativeDriver.GetColumnData(MySqlField field) at MySql.Data.MySqlClient.NativeDriver.GetColumnsData(MySqlField[] columns) at MySql.Data.MySqlClient.Driver.GetColumns(Int32 count) at MySql.Data.MySqlClient.ResultSet.LoadColumns(Int32 numCols) at MySql.Data.MySqlClient.ResultSet..ctor(Driver d, Int32 statementId, Int32 numCols) at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId) at MySql.Data.MySqlClient.MySqlDataReader.NextResult() at MySql.Data.MySqlClient.MySqlDataReader.Close() at MySql.Data.MySqlClient.MySqlCommand.ResetReader() at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader() at ASP.mysql_data_aspx.MySQLConn()

Googling for a fix, some suggestions were to add CharSet=utf8; to your connection string. Unfortunately I was unable to resolve the exception with this added.

The best way to fix this System.Collections.Generic.KeyNotFoundException with Connector/NET is to simply update your Connector/NET version. Support for utf8mb4 charset is built in in versions 6.0.8, 6.1.6, 6.2.5, 6.3.6+:

MySQL Connector/NET did not support the utf8mb4 character set. When attempting to connect to utf8mb4 tables or columns, an exception KeyNotFoundException was generated. (Bug #58244)

https://dev.mysql.com/doc/relnotes/connector-net/en/news-6-0-8.html

And MySQL Connector/NET now supports MySQL servers configured to use utf8mb4 as the default character set in version 8.0.9.

MySQL Connector/NET now supports MySQL servers configured to use utf8mb4 as the default character set.

https://dev.mysql.com/doc/relnotes/connector-net/en/news-8-0-9.html

If, for some reason, you cannot or will not update your MySQL Connector/NET version anytime soon, there is an easy workaround available; SET NAMES 'utf8'. Yes, that's right: as your first statement, set the three session system variables

  • character_set_client
  • character_set_connection
  • character_set_results

to the given character set utf8. You can even use latin1, but that may give some undesired encoding issues…

Imaging the following C# MySql.Data.MySqlClient test script for querying your MySQL database table:

string sql = "select * from aspnet_site_comments";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader rdr = cmd.ExecuteReader();

while (rdr.Read()) {
	Response.Write(rdr[0]+ "<br/>");
}
rdr.Close();
}

catch (Exception ex) {
	Response.Write(ex.ToString());
}

If your MySQL database server has in its my.cnf server config:

character_set_server utf8mb4
collation_server = utf8mb4_unicode_ci

And your table aspnet_site_comments is created using ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci, it throws an System.Collections.Generic.KeyNotFoundException exception. Alter your code to first set the character_set_* to utf8 (don't mind my pseudo-code, you'll get the idea) as a workaround for this issue:

string setcharset = "SET NAMES 'utf8'";	// <-- !!
MySqlCommand charsetcmd = new MySqlCommand(setcharset, conn);
MySqlDataReader charsetrdr = charsetcmd.ExecuteReader();
charsetrdr.Close()

string sql = "select * from aspnet_site_comments";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader rdr = cmd.ExecuteReader();

while (rdr.Read()) {
	Response.Write(rdr[0]+ "<br/>");
}
rdr.Close();
}

catch (Exception ex) {
	Response.Write(ex.ToString());
}

Only use this as a temporary fix, you should still update Connector/NET ASAP. That's it!

Donate a cup of coffee
Donate a cup of coffee

Thank you very much! <3 ❤️

7 Comments

  1. Res

    Amazing!!! I spent the whole day trying to figure this out, and this is what did it. Thanks so much!

  2. Shivam

    I Can’t Connect MySql Server This is Show Error
    the given key was not present in the dictionary

    • Hi Shivam,

      This post tries to resolve that “the given key was not present in the dictionary” issue. Also see the comment below, you may need to upgrade the Connector/NET version you’re using.

  3. Nujabes

    Hi
    I can’t connect to mysql with endpoint from lightsail mysql database in my asp.net project.

    I’m just getting the error “The given key was not present in the dictionary.”.

    Can you please check my codes below:

    var builder = new MySqlConnectionStringBuilder();
    builder.Server = “endpointfromlightsail”;
    builder.Port = 3306;
    builder.UserID = “userid”;
    builder.Password = “password”;
    builder.Database = “databasename”;
    builder.AllowUserVariables = true;
    builder.CharacterSet = “utf8”;
    builder.Pooling = false;
    builder.PersistSecurityInfo = false;

    using (MySqlConnection con = new MySqlConnection(builder.ToString()))
    {
    using (MySqlCommand com = new MySqlCommand(“SELECT * FROM databasename.users”, con))
    {
    //com.CommandType = CommandType.CommandText;
    DataSet ds = new DataSet();
    MySqlDataAdapter da = new MySqlDataAdapter(com);
    da.Fill(ds);
    foreach (DataRow drow in ds.Tables[0].Rows)
    {
    //Response.Write(“From MySql: ” + drow[1].ToString());
    }
    }
    }

    hope you help me out

    • Nujabes

      Hi
      my problem was solved now because of mysql connector/net version. Before i were using version 6.3.2.0 and upgraded to ver 6.3.9.0

      • Great to hear you resolved your own problem :)

        Might I suggest to upgrade to Connector/NET version 8.0.23? It has support for encrypted SSL/TLS connections to MySQL, which is great for security! I have an example connection for you available here: MySQL Connector/ODBC C# test script (notice SslMode=REQUIRED;).

Comments are closed