This is how i create a database and put a password:
SQLiteConnection.CreateFile(filePath + "/" + username + ".sqlite");
dbconnection = new SQLiteConnection("Data Source=" + filePath + "/" + username + ".sqlite;Version=3;");
dbconnection.Open();
dbconnection.ChangePassword(password);
sychroniseDb("Create");
This is how i check if i can connect to the database:
try{
dbconnection = new SQLiteConnection("Data Source=" + filePath + "\\" + username + ".sqlite;Version=3; Password=" + password + ";");
localDbConnected = true;
dbconnection.Open();
return true;
}
catch
{
MessageBox.Show("User or password incorrect");
localDbConnected = false;
return false;
}
The problem in this whole thing is that even if the password is wrong it's still passes the Try and doesn't go in the Catch and even opens the connection. The dll are the ones from Nuget Packages. I have Visual Studio Express 2013.
The real problem is that when i do a query it tells me is encrypted or its not a database but why it passes that try catch?
From the Sqlite website it tells that if its wrong it shouldn't connect.
I had the same problem. To be thrown exception must be made some commands. Try the following code:
try
{
var dbPath = Path.Combine(filePath, (username + ".sqlite"));
var csb = new SQLiteConnectionStringBuilder { DataSource = dbPath, Version = 3, Password = password };
dbconnection = new SQLiteConnection(csb.ConnectionString);
dbconnection.Open();
//COMMENT: Any command to check whether the database is encrypted
using (SQLiteCommand command = new SQLiteCommand("PRAGMA schema_version;", dbconnection))
{
var ret = command.ExecuteScalar();
}
localDbConnected = true;
return true;
}
catch(SQLiteException)
{
MessageBox.Show("User or password incorrect");
localDbConnected = false;
return false;
}
According to System.Data.SQLite documentation, SQLiteConnection implements System.Common.DbConnection.
SQLite implentation of DbConnection.
For a list of all members of this type, see SQLiteConnection Members .
System.Object MarshalByRefObject
Component
DbConnection
SQLiteConnection
public sealed class SQLiteConnection : DbConnection, ICloneable
The MSDN documentation states:
Notes to Inheritors When you inherit from DbConnection, you must
override the following members: Close, BeginDbTransaction,
ChangeDatabase, CreateDbCommand, Open, and StateChange. You must
also provide the following properties: ConnectionString, Database,
DataSource, ServerVersion, and State.
On DbConnection.Open the MSDN documentation states:
Opens a database connection with the settings specified by the
ConnectionString.
Thus, it makes sense for implementers to only check the password when you actually open a dbconnection. Not in the constructor.
Related
I'm trying to make it so i can use username/password i've set in the properties/settings to connect to mysql as i dont want to store mysql details in plaintext here what i'm using but not sure how to go about reading the username/password from properties, Could anyone help? thanks
private void PassTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
string MyConnection = "datasource=localhost;port=3309;username=user;password=pass123";
MySqlConnection MyConn = new MySqlConnection(MyConnection);
MySqlCommand MyCommand = new MySqlCommand("select * from applogin.users where UserId='" + this.UserTextBox.Text + "' and UserPassword='" + this.PassTextBox.Text + "' ;", MyConn);
MySqlDataReader MyReader;
recby = UserTextBox.Text;
MyConn.Open();
MyReader = MyCommand.ExecuteReader();
int count = 0;
while (MyReader.Read())
{
Console.WriteLine(MyReader[count]);
count++;
}
if (count == 1)
{
MessageBox.Show("Accepted, Welcome!");
this.Hide();
Form5 f5 = new Form5();
f5.ShowDialog();
}
else if (count > 1)
{
MessageBox.Show("Duplicate Username and passwor.\nAccess denied.");
}
else
{
MessageBox.Show("Username and password is incorrect.\nPleas try again.");
}
MyConn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
class DBConnect
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
//Constructor
public DBConnect()
{
Initialize();
}
//Initialize values
private void Initialize()
{
server = "localhost";
database = "connectcsharptomysql";
uid = "username";
password = "password";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" +
database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
}
//open connection to database
private bool OpenConnection()
{
bool flag=false;
if (this.OpenConnection() == true)
{
//Create Mysql Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//ExecuteScalar will return one value
Count = int.Parse(cmd.ExecuteScalar()+"");
flag=true;
//close Connection
this.CloseConnection();
return flag;
}
else
{
return flag;
}
}
}
I would rather recommend to read password from an environment variable instead of hardcoding it in the code.
This is a broad topic.
Mainly, it is "how to store a 'secret' well?"
I'll give some hints.
First, in dotnet CORE, there is new stuff.
https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows
That is for local development, BUT AT LEAST forces you to think about where that secret is being stored.
Using .ini, .config, .txt files and keeping a secret in plain text IS NOT secure for production scenarios.
So then you have to start thinking about "how is my code deployed?"
If you are deploying to Azure, there is Azure Key Vault.
If you are deploying to a machine/VM, then you have to consider something more robust, like Hashicorp Vault.
But you're going to get a few "quick fix" answers. You need to really consider where you keep this secret for your deployed code.
If I read your question correctly, you don't care about the connection string userid/password but about the users login credentials.
This is based on your line:
MySqlCommand MyCommand = new MySqlCommand("select * from applogin.users where UserId='" + this.UserTextBox.Text + "' and UserPassword='" + this.PassTextBox.Text + "' ;", MyConn);
And it appears you are asking about how to encrypt the password so that someone can't monitor the communication. Of course, your connection string is already an issue, but back to what I believe is your question.
It's not clear if you are using the actual user name and password as entered or not. If so, the easiest option is to use 1 way encryption - and only store the encrypted values. Then your code would get the value of the textbox and encrypt it. Then execute a query with the encrypted value (preferably with those encrypted values as parameters, not inline text.)
The result would be a query that might look like:
select * from applogin.users where UserId='kajsdf09823rcfs98dsjssdf' and UserPassword='j;las9onq;p;9wf;kjadf' ;
and written correctly (assuming you have a method named encrypt that implements whatever encryption you choose):
userId = new SqlParameter("#userName", encrypt(this.UserTextBox.Text));
userpw = new SqlParameter("#userPw", encrypt(this.PassTextBox.Text));
cmd.Parameters.Add(userId);
cmd.Parameters.Add(userpw );
cmd.CommandText = "select * from applogin.users where UserId=#userName and UserPassword=#userPw ;";
There are other great suggestions as well, I encourage you to follow up on those as well.
This method has to access a database file and perform a simple query:
private static DataTable QueryStuff(string connectionString, string[] types)
{
string queryTypes = "('" + string.Join("', '", types) + "')";
DataTable dtResults = new DataTable();
try
{
using (FbConnection myConnection1 = new FbConnection(connectionString))
{
myConnection1.Open();
FbTransaction fbTransaction = myConnection1.BeginTransaction();
FbCommand fbCommand = new FbCommand();
fbCommand = new FbCommand()
{
CommandText = "SELECT * FROM TABLE WHERE TYPE IN " + queryTypes + ";",
CommandType = CommandType.Text,
Connection = myConnection1,
Transaction = fbTransaction
};
FbDataReader dr = fbCommand.ExecuteReader();
dtResults.Load(dr);
dr.Close();
fbTransaction.Commit();
}
}
catch (Exception ex)
{
MessageBox.Show("Erro: " + ex.Message);
}
return dtResults;
}
Afterwards, the program has to delete the database file, like this:
if (File.Exists(filePath))
File.Delete(filePath);
Except, it can't, for the file is in use by 'another process'.
The program itself has created the file, and I am sure that the file is not being used in any other process.
Is there a better way to dispose this connection?
This probably has to do with the pooling option:
"Database connection pooling is a method used to keep database connections open so they can be reused by others.
Typically, opening a database connection is an expensive operation, especially if the database is remote. You have to open up network sessions, authenticate, have authorisation checked, and so on. Pooling keeps the connections active so that, when a connection is later requested, one of the active ones is used in preference to having to create another one."
(source: https://stackoverflow.com/a/4041136/14131713)
To disable this feature, you have to edit your connection string, adding "Pooling = false" to it:
$"User={user};" +
$"Password={password};" +
$"Database={path};" +
"DataSource=localhost;" +
**"Pooling=false";**
Hello i am a beginner in C# winform,
I have to connect multiple users (400 different users) through a login form ( textbox : name - password) to a single sql database with Winform C#, all users are sql users created in the database and have roles like users or admin.
I have been looking for an easy way of doing this with entity framework but couldn't find anyhting.. anyone has an idea how this can be done ?
Thanks for your help.
Does every user need their own login to the database?
If this is true you would need to write a special connection string, something like below:
using System.Data.SqlClient;
SqlConnection conn = new SqlConnection();
conn.ConnectionString =
"Data Source=ServerName;" +
"Initial Catalog=DataBaseName;" +
"User id=" + UserName + ";"
"Password=" + Password + ";";
conn.Open();
Put this in a class that accepts the username and password.
Full example:
class myConnection
{
public static SqlConnection GetConnection(string UserName, string Password)
{
string str = "Data Source=ServerName;Initial Catalog=DataBaseName;User id=" + UserName + ";Password=" + Password + ";";
SQlConnection con = new SqlConnection(str);
con.Open();
return con;
}
}
User credentials are specified in the connection string, so you need to build a connection string with the data provided by the user in the login form.
var sqlBuilder = new SqlConnectionStringBuilder();
// Set the properties for the data source.
sqlBuilder.DataSource = "ServerName";
sqlBuilder.InitialCatalog = "DatabaseName";
sqlBuilder.UserID = "USERNAME";
sqlBuilder.Password = "PASSWORD";
sqlBuilder.IntegratedSecurity = true;
// Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString();
// Initialize the EntityConnectionStringBuilder.
var entityBuilder = new EntityConnectionStringBuilder();
//Set the provider name.
entityBuilder.Provider = "System.Data.SqlClient";
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = providerString;
And then use this connection string to initialize your DbContext
var context = new DbContext(entityBuilder.ConnectionString);
I'm trying to retrieve data from database in Microsoft visual studio 2013 . I am totally lost whether I am already able to connect to the database or not and I am not sure how to retrieve data using c# as I am totally new to c#.
I am also not sure where I should put the static void main method statement before or after connectDB() method.
private void connectDB()
{
// server = "172.20.129.159";
database = "eyetracker";
server = "localhost";
// uid = "ogamaaccess";
// password = "ogama";
uid = "root";
password = "root";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
c = new MySqlConnection(connectionString);
Console.WriteLine("Connected to database");
}
private bool OpenConnection()
{
try
{
c.Open();
Console.WriteLine("Connection Opened.");
return true;
}
catch (MySqlException)
{
return false;
}
You need to install the MySql NET Connector that provides the appropriate bits to connect to MySQL database.
After installing the provider you need to add a reference to MySql.Data.Dll and add the appropriate using statement to your code
using MySql.Data.MySqlClient;
You also need to change your connection string which could be found in here.
Connection code should look something close to this:
private void Login() // login method
{
string connectString = #"uid=<UserID>;password=<Password>;
server=<IPorDomainNameOfDatabase>;
database=<DatabaseNameOnServer>;";;
using(MySqlConnection cnn = new MySqlConnection(connectString))
{
try
{
cnn.Open();
}
catch (Exception e)
{
.....
}
}
}
Full code could look something like this (command should be edited according to data you want to retrieve):
MySqlConnection connect = new MySqlConnection(connectString);
MySqlCommand command = connect.CreateCommand();
command.CommandText = "Select <VALUE> from <TABLE> order by <ID> desc limit <0,1>;";
//Command to get query needed value from DataBase
connect.Open();
MySqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
var result = reader.GetString(0);
}
Note: I strongly suggest you to put connect.Open(); into TryCatch statment, since there are many things that can do wrong and your program will crash.
I am new to C# & I am trying to programatically create & open a SQL Server database.
I have a ASP.NET webapp I am creating & on page load it should pull some data from the database (if the db doesn't exist, it should be created & populated with default data).
PS: does C#'s System.Data.SqlClient use MySQL or SQLite or something else?
Right now I am unsure if my code correctly creates a SQL Server database & if I connect to it correctly.
Can you tell me if my code is correct & how I could improve it?
UPDATE: Error is
"A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or
was not accessible. Verify that the instance name is correct and that
SQL Server is configured to allow remote connections. (provider: Named
Pipes Provider, error: 40 - Could not open a connection to SQL
Server)"}"
I have indicated where in the code below the error occurs.
Creating a SQL Server database:
// When I run this function no file seems to be created in my project directory?
// Although there is a ASPNETDB sql database file in my App_Data folder so this maybe it
public static string DEF_DB_NAME = "mydb.db"; // is this the correct extension?
private bool populateDbDefData()
{
bool res = false;
SqlConnection myConn = new SqlConnection("Server=localhost;Integrated security=SSPI;database=master");
string str = "CREATE DATABASE "+DEF_DB_NAME+" ON PRIMARY " +
"(NAME = " + DEF_DB_NAME + "_Data, " +
"FILENAME = " + DEF_DB_NAME + ".mdf', " +
"SIZE = 2MB, MAXSIZE = 10MB, FILEGROWTH = 10%) " +
"LOG ON (NAME = " + DEF_DB_NAME + "_Log, " +
"FILENAME = " + DEF_DB_NAME + "Log.ldf', " +
"SIZE = 1MB, " +
"MAXSIZE = 5MB, " +
"FILEGROWTH = 10%)";
SqlCommand myCommand = new SqlCommand(str, myConn);
try
{
myConn.Open(); // ERROR OCCURS HERE
myCommand.ExecuteNonQuery();
insertDefData(myConn);
}
catch (System.Exception ex)
{
res = false;
}
finally
{
if (myConn.State == ConnectionState.Open)
myConn.Close();
res = true;
}
return res;
}
Here's my connection to the SQL Server database code: I am pretty sure it fails to connect - if I try to use the variable conn, it says the connection is not open. Which could mean that I either failed to connect or failed to even create the db in the 1st place:
private bool connect()
{
bool res = false;
try
{
conn = new SqlConnection("user id=username;" +
"password=password;" +
"Server=localhost;" +
"Trusted_Connection=yes;" +
"database="+DEF_DB_NAME+"; " +
"connection timeout=30");
conn.Open();
return true;
}
catch (Exception e)
{
}
return false;
}
You have probably already got this figured out, but just in case people end up here with the same problem (like I did) here's how I got this working.
Your error is that the SqlConnection is not being opened, because it isn't finding an appropriate server. If you're using the SQL server express edition (as I am) you should set the SqlConnection object like this:
SqlConnection myConn = new SqlConnection("Server=localhost\\SQLEXPRESS;Integrated security=SSPI;database=master;");
Once you resolve that error though, you are going to fail on the next line when you try to execute the query. The "Filename" needs to be separated by single quotes, but you only have one on the end after the extension; you will also need one before.
Also, that is the full physical file path, and it won't use the current directory context, you have to specify a path. Make sure that the location is one which the db server will have access to when it's running, otherwise you will get a SqlException being thrown with an error message along the lines of:
Directory lookup for the file "...\filename.mdf" failed with the operating system error 5 (Access is denied). CREATE DATABASE failed. Some file names listed could not be created.
The code which I ended up using looks like this:
public static string DB_NAME = "mydb"; //you don't need an extension here, this is the db name not a filename
public static string DB_PATH = "C:\\data\\";
public bool CreateDatabase()
{
bool stat=true;
string sqlCreateDBQuery;
SqlConnection myConn = new SqlConnection("Server=localhost\\SQLEXPRESS;Integrated security=SSPI;database=master;");
sqlCreateDBQuery = " CREATE DATABASE "
+ DB_NAME
+ " ON PRIMARY "
+ " (NAME = " + DB_NAME + "_Data, "
+ " FILENAME = '" + DB_PATH + DB_NAME + ".mdf', "
+ " SIZE = 2MB,"
+ " FILEGROWTH = 10%) "
+ " LOG ON (NAME =" + DB_NAME + "_Log, "
+ " FILENAME = '" + DB_PATH + DB_NAME + "Log.ldf', "
+ " SIZE = 1MB, "
+ " FILEGROWTH = 10%) ";
SqlCommand myCommand = new SqlCommand(sqlCreateDBQuery, myConn);
try
{
myConn.Open();
myCommand.ExecuteNonQuery();
}
catch (System.Exception)
{
stat=false;
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
myConn.Dispose();
}
return stat;
}
Use this code,
internal class CommonData
{
private static SqlConnection conn;
public static SqlConnection Connection
{
get { return conn; }
}
public static void ReadyConnection()
{
conn = new SqlConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["DBConnectionString"].ToString();
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
}
public static int ExecuteNonQuery(SqlCommand command)
{
try
{
ReadyConnection();
command.Connection = conn;
int result = command.ExecuteNonQuery();
return result;
}
catch (Exception ex)
{
throw ex;
}
finally
{
command.Dispose();
if (conn.State == ConnectionState.Open) conn.Close();
conn.Dispose();
}
}
public static SqlDataReader ExecuteReader(SqlCommand command)
{
try
{
ReadyConnection();
command.Connection = conn;
SqlDataReader result = command.ExecuteReader(CommandBehavior.CloseConnection);
return result;
}
catch (Exception Ex)
{
throw Ex;
}
}
public static object ExecuteScalar(SqlCommand command)
{
try
{
ReadyConnection();
command.Connection = conn;
object value = command.ExecuteScalar();
if (value is DBNull)
{
return default(decimal);
}
else
{
return value;
}
}
catch (Exception ex)
{
throw ex;
}
}
public static void ClearPool()
{
SqlConnection.ClearAllPools();
}
}
PS: does C#'s System.Data.SqlClient use MySQL or SQLite or something else?
MySQL provides their own C# dll for connecting to their database, as do the majority of other database manufacturers. I recommend using theirs. I typically using the built-in SQL client for MS SQL (I am not aware if it can be used with other DBs).
As for this line: insertDefData(myConn) -> the method is not included in your code sample.
As for SQL debugging in general, use the GUI for debugging. I know a lot of people who grew up on MySQL do not want to, or do not understand why you should use one, but it's really a good idea. If you are connecting to MySQL, I recommend MySQL WorkBench CE; if you are connecting to a MS database, SQL Management Studio is what you want. For others, GUIs should be available. The idea here is that you can selectively highlight sections of your query and run it, something not available via command-line. You can have several queries, and only highlight the ones you want to run. Plus, exploring the RDBMS is easier via a GUI.
And if you want to prevent a SQL injection attack, just Base64 encode the string data going in.
As for the connection string itself, we will need some more data on what type of database, exactly, you are trying to connect to. Personally, I recommend just creating a separate SQL account to handle operations (easier to track, and you only need to give it permissions to what you want it to access; security and all that).