c# Xamarin SQLConnection still open and i don't know why - c#

i have a strange problem with my xamarin ios pcl app.
I have a login mechanism which checks is a sqlserver database is accessable and "if yes" then it downloads some infos from a different database. The iPad is using OpenVPN to create a connection to your network and everything seems to work great except one big issue.
1. step
The OpenVPN connection is diasbled but wifi is available (outside our network). The login method detects that the server is not available and use an another method to login.. great.
2. step
The OpenVPN connection is enabled and the sql server is reachable a´nd everything is again working perfect.
3. step
I disable the OpenVPN connection and logon again. Now the SQLConnection is initialized and the method conn.Open(); is performed. The connection state is "open" but why? There is no connection to the server available.
At the first time i thought it could be an issue that the SQLConnection object will not disposed correctly but i can't find any fault. I've checked everything, the server is really not available (used ping app) but the state is already open.
When i restart the App the sate is detected correctly again, which is an indicator that something is keeping in memory which making the sqlconnection object detecting as open.
Can anybody help me to find out why the connection is shown as open after the conenction was opened with openvpn before?
This is the method to check the connection to the sql server:
[assembly: Dependency(typeof(ADMA2.iOS.SqlServer))]
namespace ADMA2.iOS
{
/// <summary>
/// Steuerung der Datensynchronisierung mit dem SQL Server
/// </summary>
public class SqlServer: ISqlServer
{
/// <summary>
/// Contains the Error message if occur
/// </summary>
private string error = "";
public string Error
{
get { return error; }
}
public bool LoginToSqlServer(string ServerIP,
string Database,
string Username,
string Password) {
string connectionString = "Persist Security Info=false" +
";Integrated Security=true" +
";Initial Catalog=" + Database +
";Server=tcp:" + ServerIP +
";User ID=CONTEX" + #"\" + Username +
";Password=" + Password +
";Connection Timeout=10";
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
if (conn.State == ConnectionState.Open)
{
return true;
}
return false;
}
}
catch (Exception ex)
{
return false;
}
}
}
}
This is the code to check if the server is reachable
public string Login (string Username, string Password)
{
try {
// many more code here.....
var mySqlServer = DependencyService.Get<ISqlServer>(DependencyFetchTarget.NewInstance);
bool isOnline = mySqlServer.LoginToSqlServer(ConfigurationData.GetSQLServerIP(),
ConfigurationData.GetTechUserDB(),
ConfigurationData.GetTechUser(),
ConfigurationData.GetTechUserPassword());
if (isOnline) {
// Many more code here
}else{
// Many more code here
}
return "";
}catch(Exception ex){
return "Allg. Fehler:" + ex.Message;
}
} // login

I suspect you're losing the scope rather than closing the connection in your code above. Looking at MSDN's information regarding the use of 'SqlConnection.Open Method()'
If the SqlConnection goes out of scope, it is not closed. Therefore,
you must explicitly close the connection by calling Close.
Link to MSDN page
I would suggest explicitly closing the connection when you are done with it.

Related

How to save data to database using retrieved ID from datagridview?

I wanted to insert some data to the mysql database using that ID that I have retrieved from datagridview. i am new in programming. can someone please help me? thanks
First you need to download and intall
MySQL ADO.Net connector
it's the official ado.net connector for C# applications. once you intall that you can use ado.net standered data access methods to save data.
basic steps
First create a connection to the my sql data base.
Then create a command object contains the insert command.
then provide the object that contain the so called ID and finalize the command object
then Execute the command against the database.
Sample code
This is the class variables that will be used later
private MySqlConnection connection; // this MySqlConnection class comes with the connector
private string server;
private string database;
private string uid;
private string password;
This will Initialize method will configure the connection with the configuration data
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);
}
this method will open a connection to the database . you should write a C Lose method as well .because it's best practice to always close the connection after you used it
private bool OpenConnection()
{
try
{
connection.Open();
return true;
}
catch (MySqlException ex)
{
//When handling errors, you can your application's response based
//on the error number.
//The two most common error numbers when connecting are as follows:
//0: Cannot connect to server.
//1045: Invalid user name and/or password.
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server. Contact administrator");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
This will insert a record to database . query will contains the T-SQL query that runs against the database
public void Insert()
{
string query = "INSERT INTO tableinfo (name, age) VALUES('John Smith', '33')";
//open connection
if (this.OpenConnection() == true)
{
//create command and assign the query and connection from the constructor
MySqlCommand cmd = new MySqlCommand(query, connection);
//Execute command
cmd.ExecuteNonQuery();
//close connection
this.CloseConnection();
}
}
Hope this will help

Unable to connect to remote host

I'm having an issue when connecting to a remote host. I am able to connect to my local server with a copy of the database.
I'm trying to connect to the XenForo DB on my web host and get some information. All is working on localhost.
private static MySqlConnection _connection =
new MySqlConnection("Server=ip; database=ls-v_forum; UID=ls-v_forum; password=pass");
public static int? FetchUserId(string emailoruser)
{
MySqlCommand userCommand = new MySqlCommand("SELECT * FROM xf_user WHERE username='" + emailoruser + "'", _connection);
MySqlCommand emailCommand = new MySqlCommand("SELECT * FROM xf_user WHERE email='" + emailoruser + "'", _connection);
_connection.OpenAsync();
}
That's the code and it's throwing this error
Connection must be valid and open.
at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
at MySql.Data.MySqlClient.MySqlCommand.CheckState()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior
behavior)
EDIT
public int? FetchUserId(string emailoruser)
{
using (var _connection = new MySqlConnection("server=ip; database=ls-v_forum; UID=ls-v_forum; password=pass"))
{
MySqlCommand userCommand = new MySqlCommand("SELECT * FROM xf_user WHERE username='" + emailoruser + "'", _connection);
MySqlCommand emailCommand = new MySqlCommand("SELECT * FROM xf_user WHERE email='" + emailoruser + "'", _connection);
_connection.Open();
MySqlDataReader userReader = userCommand.ExecuteReader();
int? userId = null;
while (userReader.Read())
{
userId = userReader.GetInt32("user_id");
}
userReader.Close();
if (userId == null || userId == 0)
{
MySqlDataReader emailReader = emailCommand.ExecuteReader();
while (emailReader.Read())
{
userId = emailReader.GetInt32("user_id");
}
emailReader.Close();
}
_connection.Close();
return userId;
}
}
MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any
of the specified MySQL hosts.
at MySql.Data.MySqlClient.NativeDriver.Open()
at MySql.Data.MySqlClient.Driver.Open()
at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder
settings)
at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open()
I didn't attempt to troubleshoot your connection command, but the following works for me when connecting to a SQL DB on a remote machine
You can provide the machine name even if it is the local machine, so the code below will work if the program is running on the same machine as the database or if the program is running on one machine and the database is on another, so long as the two machines are networked AND the account you're running the program under has access to the machine and instance and database.
Please note in example below, the "default" instance name (MSSQLSERVER) was used when SQL was installed. When the DB instance name is the default name, then you must not provide an instance name explicitly (you'll get an error if you do). The only time you provide an instance name explicitly is when it is not the default instance name. The code below can handle either scenario (by setting dbInstanceName variable to "" or an instance name, e.g. "\SQLEXPRESS"). See S.O. SQL Server: How to find all localdb instance names. When it doubt, try an empty instance name and a name you believe to be the instance name to see what works.
string databaseMachineName = "machine_name";
string databaseInstanceName = "";
string dbName = "database_name";
using (SqlConnection sqlConnection = new SqlConnection("Data Source=" + databaseMachineName + databaseInstanceName + "; Initial Catalog=" + dbName + "; Integrated Security=True;Connection Timeout=10"))
{
.
.
.
}
I'm having an issue when connecting to a remote host.
Not necessarily. According to the error, the issue isn't that you can't connect. It's that you're trying to use a connection that isn't connected:
Connection must be valid and open.
Specifically where you execute a command:
MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
Which isn't in the code you're showing. However, there are a couple of fundamental mistakes that are in the code you're showing which would easily lead to an error like this:
1. Using a static shared connection object.
This is a famously bad idea. We've probably all tried it, and we've probably all run into issues exactly like this one. The underlying system is pretty efficient at creating/pooling/using/disposing database connections. Don't try to optimize for it. Instead, you should create/use/dispose your connections in as small a scope as possible. For example:
using (var connection = new MySqlConnection(SOME_CONNECTION_STRING))
{
var userCommand = new MySqlCommand(SOME_COMMAND_STRING);
// use the command, get the data you need from it
}
// leave the context of the database and return to business logic, UI, etc.
This is because keeping complex things like database connections synchronized is hard, and keeping connections open is expensive. Let the underlying system open/pool/close connections.
2. Not awaiting an async operation.
What would happen here?:
connection.OpenAsync();
userCommand.ExecuteNonQuery();
An error. Because the code didn't await the asynchronous operation, so the connection isn't open when you're trying to use it. Either don't use the asynchronous operation:
connection.Open();
userCommand.ExecuteNonQuery();
or await it:
await connection.OpenAsync();
userCommand.ExecuteNonQuery();
(And obviously make the containing method async, and its callers should await it, etc.) But definitely don't try to use a connection before it's had a chance to open.
3. (Unrelated, but still important) Your code is vulnerable to SQL injection.
SQL injection happens right here:
"SELECT * FROM xf_user WHERE username='" + emailoruser + "'"
Where did emailoruser come from? Was it user input? Was it a value pulled from data which was previously provided by a user? How trustworthy is it? What this string-concatenation approach does is allow any user to execute any SQL code they want on your database. Instead, use query parameters and treat user input as values instead of as executable code.

SQL Exception - Network-related or instance specific. SQL Express "It works on my machine" issue

EDIT: It only took a week but I eventually found out the issue, primarily due to pure luck and another error with a more specific fix.
The issue was with the connStr I had made, which for some reason on this machine gave me the error randomly of "System.ArgumentException: Keyword not supported: 'datasource'." during runtime. I then found out a fix for that was to rename the connStr as follows:
connStr = #"server = (server name); Initial Catalog = AutoTestDB; Integrated Security = true";
Should you have this error as I have, try that method of connection. END EDIT
I'm currently working on Automated Testing using Katalon Automated Testing, essentially Selenium for Chrome, and whenever I'm attempting to add the results of the test to our Test Results Database the SQL Exception "A network-related or instance-specific error occurred while establishing a connection to SQL Server. " keeps popping up. TCP/IP is open, as is firewall and remote connections, and I have the SQL-SMS open and running while I run the database with the SQL connection.
However it only happens whenever I'm using a certain machine to access the database which is stored within the machine itself, as it is with every other machine that I use and they all work perfectly fine. The only difference I can think of for this machine is that it uses SQL Express while all the others that I use have the full version of Microsoft SQL-SMS-17.
It's a genuine case of "It works on my machine", except with the caveat that it works on several others and even across different users as we are all working on this automated testing, this machine is the lone exception for this code not working, with the only difference being that it uses SQL Express which should be accounted for with the \\SQLExpress.
C# code with SQL connetions to edit the values into an already made table within the database.
public void testDBAdd(String testName, Boolean pass, String testComment)
{
SqlConnection con;
SqlDataAdapter daAutoTest;
DataSet dsAutoTestDB = new DataSet();
SqlCommandBuilder cmdBAutoTest;
String connStr, sqlAutoTest;
connStr = #"datasource = .\\sqlexpress; Initial Catalog = AutoTestDB; Integrated Security = true";
con = new SqlConnection(connStr);
sqlAutoTest = #"SELECT * FROM TestResults";
daAutoTest = new SqlDataAdapter(sqlAutoTest, connStr);
cmdBAutoTest = new SqlCommandBuilder(daAutoTest);
daAutoTest.FillSchema(dsAutoTestDB, SchemaType.Source, "AutoTest");
daAutoTest.Fill(dsAutoTestDB, "AutoTest");
foreach (DataRow drAutoTest in dsAutoTestDB.Tables["AutoTest"].Rows)
{
if (pass == true && drAutoTest["testName"].ToString() == testName)
{
drAutoTest.BeginEdit();
drAutoTest["testName"] = testName;
drAutoTest["testResult"] = 1;
drAutoTest["testComment"] = testComment;
drAutoTest.EndEdit();
daAutoTest.Update(dsAutoTestDB, "AutoTest");
}
else if (pass == false && drAutoTest["testName"].ToString() == testName)
{
drAutoTest.BeginEdit();
drAutoTest["testName"] = testName;
drAutoTest["testResult"] = 0;
drAutoTest["testComment"] = "Exception: " + testComment;
drAutoTest.EndEdit();
daAutoTest.Update(dsAutoTestDB, "AutoTest");
}
}
}
Code which runs the actual test and gathers if it has passed or failed due to the presence of certain elements, in this case is a certain page displayed when the user logs in and clicks a button.
public void settingTest<TestNumber>()
{
IWebDriver driver = new ChromeDriver();
ChromeOptions options = new ChromeOptions();
options.AddArguments("--start-maximized");
driver = new ChromeDriver(options);
String testName = "<Test Number>", testComment = "";
Boolean pass = false;
try
{
settingsLogin(driver);
settingsClick(driver);
Assert.IsTrue(driver.FindElement(ElementLocator).Displayed);
if (driver.FindElement(ElementLocator).Displayed == true)
{
testComment = "Pass";
pass = true;
testDBAdd(testName, pass, testComment);
}
}
catch (Exception ex)
{
testComment = "" + ex.TargetSite + "" + ex.Message;
testDBAdd(testName, pass, testComment);
}
finally
{
driver.Close();
}
}
Not sure, but I think your connection string has an extraneous backslash. You've prefaced the string with a "#" but then used "\\" in the Data Source. You might also try "(localdb)\SQLExpress" as the data source.
It only took a week but I eventually found out the issue, primarily due to pure luck and another error with a more specific fix. The issue was with the connStr I had made, which for some reason on this machine gave me the error randomly of "System.ArgumentException: Keyword not supported: 'datasource'." during runtime. I then found out a fix for that was to rename the connStr as follows:
connStr = #"server = (server name); Initial Catalog = AutoTestDB; Integrated Security = true";
Should you have this error as I have, try that method of connection. And thanks to the users who tried to help in both the comments of the post and in the answers section of this post.

Object reference not set to an instance of an object with inserting data into database

I created a connection with a Microsoft sql database and am trying to add basic informastion as part of an exercise but get the following error.
Object reference not set to an instance of an object
This is how I connect to the database
SqlConnection sqlConn;
protected void butConnect_Click(object sender, EventArgs e)
{
try
{
string connectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=lrmg;Integrated Security=True;";
sqlConn = new SqlConnection(connectionString);
sqlConn.Open();
labMessage.Text = "a connection to your database was established";
}
catch (SqlException sqlE)
{
labMessage.Text = sqlE.Message;
}
catch (Exception exe)
{
labMessage.Text = exe.Message;
}
Here is where I get the error
protected void butSubmit_Click(object sender, EventArgs e)
{
try
{
string name = txtName.Text;
string date = txtDate.Text;
**SqlCommand cmd = sqlConn.CreateCommand();**
cmd.CommandText = "INSERT INTO Canditate(Name, Doj) VALUES('" + name + "'," + date + ")";
cmd.ExecuteNonQuery();
labMessage.Text = "The value was inserted into your database";
}
catch (SqlException sqlE)
{
labMessage.Text = sqlE.Message;
}
catch (Exception exe)
{
labMessage.Text = exe.Message;
}
}
I am under the impression that the sql connection was opened so why the exception?
You are getting the error because reference variable sqlConn is null - that is happening probably because
From you code snippet, connection is getting created and opened in
connect button click. So you need to hit connect before submit
Most likely cause is probably different assuming that this ASP.NET code - in such case, every request is served by different instance of page class - so if you open connection on one request (connect click), it (that variable) won't be available in next request (submit click). The remedy is simple - create and open connection when you need it i.e. in submit click. On the other hand, you probably need to understand mode about web programming models to avoid such mistakes.
You use two different events to do your work on the database. Why? Have you ever heard of connection pooling?
Probably between the first event (open connection) and second event (db insert) something happens and change your global variable SqlConn to null and you get the error. (Of course I am assuming that you press that button to open the connection before trying to insert anything)
With connection pooling this kind of programming pattern is no more necessary, instead, when you need to update/insert/delete/select something you open the connection, do your work and close immediately the connection without keeping it open and consuming resources on the server and client side.
try
{
string connectionString = "Data Source=.\\SQLEXPRESS;" +
"Initial Catalog=lrmg;Integrated Security=True;";
using(SqlConnection sqlConn = new SqlConnection(connstring))
{
SqlCommand cmd = sqlConn.CreateCommand();**
cmd.CommandText = "INSERT INTO Canditate(Name, Doj) VALUES(#name, #dt)";
cmd.Parameters.AddWithValue("#name", txtName.Text);
cmd.Parameters.AddWithValue("#dt", Convert.ToDateTime(txtDate.Text));
cmd.ExecuteNonQuery();
labMessage.Text = "The value was inserted into your database";
}
}
catch (SqlException sqlE)
{
labMessage.Text = sqlE.Message;
}
catch (Exception exe)
{
labMessage.Text = exe.Message;
}
Notice also that your code is subject to Sql Injection attacks because you use string concatenation to build your sql text. This is a bad practice that should be avoided at all costs
You should have a dedicated method to open the connection, that you'd invoke every time you're using the connection. With your current setup, butConnect_click MUST be called before butSumbit_Click in the same request. So add the call to butConnect in butSubmit.

C# connecting to a database

I Am Trying to create a program using c# that needs to connect to a database running on a Solaris server, I am not too familiar with the server, we normally use dbVisualizer to connect to it. the driver it uses to connect is mysql-connector-java-5.1.10, which is a jdbc driver. was wondering what drivers to use to connect to the database using C# and what is the syntax used to establish the connection. as far as I know I will be unable to install any drivers on the server side, and i will only be able to make changes/Install what is required on the client.
If I read your question correctly you are trying to connect to a MySql database from c#. This can be achieved by downloading the .net connector for MySql - Connector/Net. When you install this driver it will "integrate" with Visual Studio and you will be able to connect to the server directly from Visual Studio and your Program that will use the driver.
On the question on the syntax to connect you will either need to use MySqlConnection, with a tutorial here - http://bitdaddys.com/MySQL-ConnectorNet.html, or use something like the ADO.NET Entity Framework. But that depends on your Tastes.
I am assuming this Server can be access over the network.
Update User Confused about Connection String
Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
You pass that string to the connection without any JDBC:// prefixes.
Please Note haven't done this in a while so the connection string could be wrong (So correct me If I'm wrong) and if you forget any connection string in the future you can always use a website like http://www.connectionstrings.com/ which shows them all for you. That is where I got the string above.
Hope that helps.
I believe this is what you want to connect (on the server):
http://dev.mysql.com/downloads/connector/net/1.0.html
You can try your connection like this:
string MyConString = "SERVER=yourserver;" +
"DATABASE=mydatabase;" +
"UID=testuser;" +
"PASSWORD=testpassword;";
MySqlConnection connection = new MySqlConnection(MyConString);
You would probably want to follow the normal guidelines for IDisposable classes (use using etc.).
using MySql.Data.MySqlClient;
using System.Windows;
class Connexion
{
public MySql.Data.MySqlClient.MySqlConnection connexion;
private string server;
private string database;
private string uid;
private string password;
public Connexion()
{
server = "localhost";
database = "GestionCommeriale";
uid = "root";
password = "";
String connexionString;
connexionString = "SERVER=" + server + ";" + "DATABASE=" + database + ";" +
"UID" + uid + ";" + "PASSSWORD =" + password + ";";
connexion = new MySqlConnection(connexionString);
}
public bool OpenConnexion()
{
try
{
connexion.Open();
return true;
}
catch (MySqlException ex)
{
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server. Contact administrator");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
public bool ColseConnexion()
{
try
{
connexion.Close();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
}
}

Categories