I’m trying to connect to my Mariadb database that’s inside a Docker container. I’ve looked at Microsoft’s documentation and searched on Google to find out why I’m getting an error message saying that there’s nothing to retrieve from the database. It’s strange because when I try to debug my code, it doesn’t execute the lines that check the database. The error happens at the line "conn.Open();" and then it just stops. I can also see in Docker that it’s getting a connection, so the connection string should be correct. Can anyone explain what I’m doing wrong?
This is the error message:
System.InvalidCastException: ‘Object cannot be cast from DBNull to
other types.’
Here is my code:
using MySql.Data.MySqlClient;
namespace DockerBase
{
internal class UserDB
{
public bool ValidateUser(string username, string password)
{
try
{
MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder();
builder.Server = "localhost";
builder.Port = 3306;
builder.UserID = "root";
builder.Password = "rootpassword";
builder.Database = "userDB";
using (MySqlConnection conn = new MySqlConnection(builder.ConnectionString))
{
conn.Open();
string sql = "SELECT COUNT(*) FROM users WHERE username = @username AND password = @password;";
int result = 0;
using (MySqlCommand cmd = new MySqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@username", username);
cmd.Parameters.AddWithValue("@password", password);
result = Convert.ToInt32(cmd.ExecuteScalar());
}
bool isValid = (result > 0);
return isValid;
}
}
catch (MySqlException e)
{
Console.WriteLine("Error connecting to MySQL database: " + e.Message);
return false;
}
}
}
}
And here is my dockerfile also
FROM mariadb:latest
ENV MYSQL_DATABASE=userDB
ENV MYSQL_USER=myuser
ENV MYSQL_PASSWORD=mypassword
ENV MYSQL_ROOT_PASSWORD=rootpassword
# Copy SQL scripts
COPY createUser.sql /docker-entrypoint-initdb.d/
EXPOSE 3306
And also my sql code:
USE userDB;
DROP TABLE IF EXISTS users;
CREATE TABLE users (
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
);
INSERT INTO users (username, password) VALUES ('admin', 'admin');
In the terminal in Dockerhub I can see that a connection is being made:
Aborted connection 3 to db: ‘userDB’ user: ‘root’ host: ‘REMOVED’ (Got an error reading communication packets)
3
Answers
The problem is something with using mariadb. When i press the login button again it then works, so something with the first connection now being completely establish. I changed the Dockerfile so that it uses the latest version of MySQL instead and that fixed the problem.
builder.Server = "localhost";
Change this line so that it contains your container name, not localhost, like following:
builder.Server = "mysql-container-name";
This is done due to docker containers not sharing localhost.
We have this error message:
Specifically,
DBNull
is NOT a concept the MySQL database knows about. It’s a special value in the client .Net code used for representingNULL
s returned from an SQL query. It’s needed as a distinct item from the normal C#null
reference because the primitive value types likeint
andDateTime
don’t have anull
concept of their own to map to the corresponding SQLInteger
andDatetime
types, and the ADO.Net library pre-dates .Net nullable value types (int?
,DateTime?
, etc).Therefore, the only way you could get this error is after you’ve successfully run a query. In other words, the connection worked and completed just fine, and the error occurs after the
ExecuteScalar()
call is finished.Most likely, the
COUNT(*)
expression (somehow) results inNULL
on the SQL side, which ADO.Net will express asDBNull.Value
for C#, and theConvert.ToInt32()
function doesn’t know what to do with this.This is different than not returning any rows. The
ExecuteScalar()
function should return a basic C#null
reference if the result set is empty, which is different fromDBNull
, if there are no rows.