Runs a MySQL query, returns Dictionary or false;
As you suspected, this code is pretty bad. You are returning three different types of data here. Just, don't.

1)


try
{
    conn.Open();
}
catch (MySqlException ex)
{
    return ex;
}



Don't return the exception, re-throw it and catch it in the caller.

try
{
    conn.Open();
}
catch (MySqlException ex)
{
    throw;
}


In this block, you are catching the exception, then returning the exception to the user as a piece of data. A better way to do this would be to just not catch the exception and let the caller catch it:

try
{
    return mysqlWrapper.RunSelectCommand(C, collection);
}
catch (Exception ex)
{
    return ex;
}


However, now you are exposing your call stack to the user, which you don't want to do. This information could provide hints to someone trying to break into your system, and is not allowed under some security protocols (SOC 2, for example). Instead of returning the whole exception, build a new piece of data and return just the relevant bits (or if they just need one piece, then just return that piece).

2)

Don't return false. Either return an empty object (if the caller doesn't care if there were no results), or throw an exception. Alternately, you could use a ValueTuple and return (bool success, Dictionary&lt;string, string&gt; data) from the method. The first successful path would return (true, {data}) and the second would return (false, null).

3)

You might have a SQL Injection attack going on here. Check out what happens if the client sends a request with the text parameter "test' or 1 = 1 --". It looks like the resulting query might be SELECT * FROM api WHERE apikey = 'test' or 1 = 1 --', but I don't know this well enough to be sure.