Connection timeout in server - c#

I want to ask about connection timeout since I have a problem with it.
The error is
"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occured because all pooled connections were in use and max pool size was reached."
Can code like this cause a connection to timeout?
What is best practice to call connection??
using (var cnn = OpenExternalContractor()) //call connection string
{
var query = #"insert into interfaceRequest (requestNo,requestAssemblyName,requestApplicationName,requestFunctionName,
requestParameters,requestUserName,requestUserMail,requestDate)
values (#requestNo,#requestAssemblyName,#requestApplicationName,#requestFunctionName,
#requestParameters,#requestUserName,#requestUserMail,getDate())";
cnn.Execute(query, new
{
requestNo = requestNo,
requestAssemblyName = requestAssemblyName,
requestApplicationName = jobName.Split('-')[0],
requestFunctionName = jobName.Split('-')[1],
requestParameters = requestParameters,
requestUserName = requestUserName.Replace("\"", "\\"),
requestUserMail = userMail
});
//Call another function here that call connection string
PersonnelRepository.UpdateLastNumber(requestNamePrefix, Convert.ToInt32(lastNumber));
}
public static void UpdateLastNumber(string type, int value)
{
using (var cnn = OpenExternalContractor()) //Call connection string
{
var query = "update AutoNumber set LastNumber = " + value + " where Type = '" + type + "'";
cnn.Query<int>(query);
}
}
Here are the code for connection string:
protected static IDbConnection OpenExternalContractor()
{
IDbConnection dbConnection = new SqlConnection(WebConfigurationManager.ConnectionStrings["ExternalContractor"].ConnectionString);
dbConnection.Open();
return dbConnection;
}
Thanks,

When getting the string of your connection by using WebConfigurationManager.ConnectionStrings["ExternalContractor"].ConnectionString, you can change in your WebConfig file the connection timeout by altering this connection string like this for example :
Data Source=(local);
Initial Catalog=AdventureWorks;
Integrated Security=SSPI;
Connection Timeout=30
From social.msdn.microsoft.com

Related

Fastest and right way to check if I have a connection to SQL Server in C#

I just want to check if I have a connection to a SQL Server for a sync my local database to it. And if I don't have to skip on it.
Also, it should work with wifi and cable connection.
When it connects with wifi some time my network is off but the method
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
returns true so this method does not work well for me.
I also try just to check the connection to my SQL Server like that
public bool TestServerConnection()
{
using (SqlConnection openCon = new SqlConnection(connectionString))
{
try
{
string saveStaff = "select 1";
SqlCommand command = new SqlCommand(saveStaff, openCon);
command.CommandTimeout = 1;
openCon.Open();
if (openCon.State == ConnectionState.Open)
{
return true;
}
else
{
return false;
}
}
catch (Exception)
{
return false;
}
}
}
With this connection string
Data Source=CV-TED-SQL1;Initial Catalog = PulserDb; Integrated Security=true;MultipleActiveResultSets=True;
But when I have no connection for example when I change Data Source=CV-TED-SQL1; to Data Source=CV-TED-SQL11;, the openCon.Open(); takes about 10 seconds..
That just too long..
There is any fastest way to do that?
I can't change my connection string, maybe I can change it only for my method and change it back when this method end
Thanks for the help.
EDITING A NEW TEST METHOD
public bool TestServerConnection()
{
Stopwatch stopwatch = Stopwatch.StartNew();
string tempCS = connectionString;
SqlConnectionStringBuilder scb = new SqlConnectionStringBuilder(tempCS);
scb.ConnectTimeout = 1;
using (SqlConnection openCon = new SqlConnection(scb.ToString()))
{
try {
string saveStaff = "select 1";
SqlCommand command = new SqlCommand(saveStaff, openCon)
{
CommandTimeout = 1
};
openCon.Open();
if (openCon.State == ConnectionState.Open)
{
stopwatch.Stop();
return true;
}
else
{
stopwatch.Stop();
return false;
}
}
catch (Exception)
{
stopwatch.Stop();
return false;
}
}
}
If you cannot change the connection string to add a Connect Timeout key then you can change the connection string at runtime with little effort using the SqlConnectionStringBuilder as shown below
SqlConnectionStringBuilder scb = new SqlConnectionStringBuilder(connectionString);
scb.ConnectTimeout = 5; // 5 seconds wait 0 = Infinite (better avoid)
connectionString = scb.ToString();
Console.WriteLine(connectionString);
using(SqlConnection cnn = new SqlConnection(connectionString)
{
}

C# SQL Connection String returning error

Hi I'm new when it comes to connecting to a server/database and was wondering why this returns an error.
I have a FastHost server with a database.
I've just put in an example IP but i have been using the one given on my control panel on the site.
private void SQLTest_Click(object sender, RoutedEventArgs e)
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString =
"Data Source = 123.456.789.012" +
"Initial Catalog = DiscoverThePlanet" +
"User ID = TestUser" +
"Password = Test";
try
{
conn.Open();
MessageBox.Show("Connection Established!");
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open Connection!");
}
}
This returns the
Can not open Connection!" message.
I get the following show in my code:
An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll but was not handled in user code
Additional information: 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 know my server is fine because i have connected to it on SQL Server Management studio and added tables and data.
You're missing a couple of ;
conn.ConnectionString =
"Data Source = 123.456.789.012" +
";Initial Catalog = DiscoverThePlanet" +
";User ID = TestUser" +
";Password = Test";
An even better solution is to use ConnectionStringBuilder.
System.Data.SqlClient.SqlConnectionStringBuilder builder =
new System.Data.SqlClient.SqlConnectionStringBuilder();
builder["Data Source"] = "123.456.789.012";
builder["Initial Catalog"] = "DiscoverThePlanet";
builder["User ID"] = "TestUser";
builder["Password"] = "Test";
Console.WriteLine(builder.ConnectionString);
Or (as #Fischermaen mentioned) you can use the properties, instead of indexes. It's even more readable!
builder.DataSource = "123.456.789.012";
builder.InitialCatalog = "DiscoverThePlanet";
builder.UserID = "TestUser";
builder.Password = "Test";
Also, in this scenario you aren't using any user input, but beware of connection string injection when manually creating your connection string. ConnectionStringBuilder can help you avoid those.
A connection string injection attack can occur when dynamic string
concatenation is used to build connection strings that are based on
user input. If the string is not validated and malicious text or
characters not escaped, an attacker can potentially access sensitive
data or other resources on the server. For example, an attacker could
mount an attack by supplying a semicolon and appending an additional
value. The connection string is parsed by using a "last one wins"
algorithm, and the hostile input is substituted for a legitimate
value.
The connection string builder classes are designed to eliminate
guesswork and protect against syntax errors and security
vulnerabilities. They provide methods and properties corresponding to
the known key/value pairs permitted by each data provider. Each class
maintains a fixed collection of synonyms and can translate from a
synonym to the corresponding well-known key name. Checks are performed
for valid key/value pairs and an invalid pair throws an exception. In
addition, injected values are handled in a safe manner.
A last (and, in my opinion, best) alternative is to move your connectionstring from code into a config. This will make it much easier for you to use the same code in different environments.
conn.ConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionString];
And your config.
<connectionStrings>
<add name="MyConnectionString" connectionString="[ConnectionString goes here]" providerName="System.Data.SqlClient" />
</connectionStrings>
Add a semicolon after each part of your connection string code:
private void SQLTest_Click(object sender, RoutedEventArgs e)
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString =
"Data Source = 123.456.789.012;" +
"Initial Catalog = DiscoverThePlanet;" +
"User ID = TestUser;" +
"Password = Test";
try
{
conn.Open();
MessageBox.Show("Connection Established!");
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open Connection!");
}
}
https://www.connectionstrings.com/sql-server/ should tell you more about the correct format.
Your connectionstring is not well formated, you forgot some ; :
"Data Source = 123.456.789.012;Initial Catalog = DiscoverThePlanet;User ID = TestUser;Password = Test"
An example :
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;
https://www.connectionstrings.com/sql-server/
There are some ';' missing. Try this:
conn.ConnectionString =
"Data Source = 123.456.789.012;" +
"Initial Catalog = DiscoverThePlanet;" +
"User ID = TestUser;" +
"Password = Test;";
Use StringBuilder if you wants to write ConnectionString like mention,
String object it will occupy memory each time.
StringBuilder will occupy memory only once, so it will give you better performance.
SqlConnection conn = new SqlConnection();
StringBuilder sb=new StringBuilder();
sb.Append("Data Source = 123.456.789.012;");
sb.Append("Initial Catalog = DiscoverThePlanet;");
sb.Append("User ID = TestUser;");
sb.Append("Password = Test;");
conn.ConnectionString =sb.ToString();
try
{
conn.Open();
MessageBox.Show("Connection Established!");
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open Connection!");
}
Semi Column is missing in the Connection String. So correct it
private void SQLTest_Click(object sender, RoutedEventArgs e)
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString =
"Data Source = 123.456.789.012;" +
"Initial Catalog = DiscoverThePlanet;" +
"User ID = TestUser;" +
"Password = Test;";
try
{
conn.Open();
MessageBox.Show("Connection Established!");
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open Connection!");
}
}

Too many sessions are open error, while creating connection to Sql Server Ce

My C# application uses Sql Server Compact Edition in which I got connections to the database here and there. I use this method to run ExecuteScalar and I use it repetitive in some point.
This is the class:
//_cnt & _cmd are private variables
public static object Run_ExecuteScaler(string query)
{
object objResult;
_cnt = new SqlCeConnection {ConnectionString = ConnectionString};
_cmd = new SqlCeCommand
{
Connection = _cnt,
CommandType = System.Data.CommandType.Text,
CommandText = query
};
if (_cnt.State != System.Data.ConnectionState.Open)
_cnt.Open();
objResult = _cmd.ExecuteScalar();
_cmd.Dispose();
if (_cnt.State != System.Data.ConnectionState.Closed)
_cnt.Close();
_cnt.Dispose();
return objResult;
}
I use this line in a foreach loop which uses the above method to ctreate a connection to the database and run the command. It then closes the connection and disposes it.
var middleCat = RSSql.Run_ExecuteScaler(string.Format(
"SELECT Implication FROM tblMiddleCategory where IDMiddleCategory='{0}'",someInt));
But I'm getting this error after second loop:
Too many sessions are open
I realize that this usually happens when a connection hasn't been disposed. but I do it in my method. So Am I doing it in a wrong way?
Update
I changed the method to use using statement as #Damien_The_Unbeliever offered:
public static object Run_ExecuteScaler(string query)
{
object objResult = null;
using (_cnt = new SqlCeConnection( ConnectionString))
{
_cmd = new SqlCeCommand
{
Connection = _cnt,
CommandType = System.Data.CommandType.Text,
CommandText = query
};
if (_cnt.State != System.Data.ConnectionState.Open)
_cnt.Open();
objResult = _cmd.ExecuteScalar();
}
return objResult;
}
But I'm still getting the same error.

C# method returns connect to different databases

UPD:
I have a static class for work with database.
This class contains the method which returns connect to database. Early this method returns connect to Advantage database (AdsConnection):
static private AdsConnection GetConnection(){
var conn = new AdsConnection();
conn.ConnectionString = here my connection string
return conn;
}
Now, I need to change this method. I need that this method returns connect to different databases types (Advantage database, Oracle database).
The method will work into public methods in my class. For example, method for get data from any table from database.
public static List<entity1> GetEntities(){}
Into this method the first of my step is to resolve the type of database, then connect to database. Then get data from database and the last step is return data (List< entity1 >).
In the step to connect the database I need to use the method GetConnection("Ads")
This method returns current connect to database and then I can use this connect for work
I changed method:
My first version
static private T GetConnection<T>(string dbType)
{
if (dbType.Equals("Oracle"))
{
OdbcConnection conn = new OdbcConnection
conn.ConnectionString = here my connection string
return (T)conn;
}
if (dbType.Equals("Ads"))
{
AdsConnection conn = new AdsConnection
conn.ConnectionString = here my connection string
return (T)conn;
}
return default(T);
}
But, my solution does not work. I have errors:
Cannot convert type 'System.Data.Odbc.OdbcConnection' to 'T'
Cannot convert type 'Advantage.Data.Provider.AdsConnection' to 'T'
I do not know how to resolve my problem.
Please, tell me how to resolve my problem?
Now, I use the following code (this solution give me #khlr):
static private IDbConnection GetConnection(string dbType)
{
if (dbType.Equals("Oracle"))
{
OdbcConnection conn = new OdbcConnection
conn.ConnectionString = here my connection string
return conn;
}
if (dbType.Equals("Ads"))
{
AdsConnection conn = new AdsConnection
conn.ConnectionString = here my connection string
return conn;
}
return null;
}
Thank.
One way you can abstract the connection instantiation is by using DbProviderFactory of ADO.Net. You can basically pass it a provider name and it will give a connection based on the provider. This basically reduce the check of dbtype etc for you and I think its sensible approach when you need to target multiple database. Some of the code snippet are copied from MSDN.
In you config file you can multiple connection string set up with different database type and provider.
<configuration>
<add name="NorthwindAccess"
providerName="System.Data.OleDb"
connectionString=
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Northwind.mdb;"
/>
Then in you method you can do following:
static DbConnection CreateDbConnection(
string providerName, string connectionString)
{
// Assume failure.
DbConnection connection = null;
// Create the DbProviderFactory and DbConnection.
if (connectionString != null)
{
try
{
DbProviderFactory factory =
DbProviderFactories.GetFactory(providerName);
connection = factory.CreateConnection();
connection.ConnectionString = connectionString;
}
catch (Exception ex)
{
// Set the connection to null if it was created.
if (connection != null)
{
connection = null;
}
Console.WriteLine(ex.Message);
}
}
// Return the connection.
return connection;
}
You could do the following, since both connections inherit from IDbConnection:
static private IDbConnection GetConnection(string dbType)
{
if (dbType.Equals("Oracle"))
{
OdbcConnection conn = new OdbcConnection
conn.ConnectionString = here my connection string
return conn;
}
if (dbType.Equals("Ads"))
{
AdsConnection conn = new AdsConnection
conn.ConnectionString = here my connection string
return conn;
}
return null;
}

An established connection was aborted by the software in your host machine C# error connect to SQL Server

I programmed a Windows service which gets strings from a client using TCP socket and saves them to a database. It's connect and no have error send/receive. But in first, service can't connect to SQL Server database :
string sql = "Select * from [Commands] Where [cName]='" + _cName + "'";
pr = new Persistance();
using (var item = pr.sqlDataReader(sql))
{
return new Commands
{
cID = item.GetInt32(0),
cName = item.GetString(1),
cType = item.GetInt32(2),
msgID = item.GetInt32(3)
};
}
My persistance class;
public SqlDataReader sqlDataReader(string sqlCommand)
{
connection = new SqlConnection(connectionString);
connection.Open();
return new SqlCommand(sqlCommand, connection).ExecuteReader();
}
What I miss I can't understand. it write in catch side :
An established connection was aborted by the software in your host machine
First of all, you should use parametrized queries to avoid SQL injection attacks - so you'll need to modify your SELECT statement:
string sql = "Select * from [Commands] Where [cName]= #cname";
and you'll need to somehow define that parameter and set its value - not sure what your Persistance class is that you're using - in raw ADO.NET, it would be something like:
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.Parameters.Add("#cname", SqlDbType.VarChar, 100).Value = _cName;
Next, when using a SqlDataReader, you must call .Read() on that data reader to actually get the data:
using (var item = pr.sqlDataReader(sql))
{
// call .Read() on the SqlDataReader - and this *COULD* return multiple rows!
// Not just one - it could return many - so you'll need to handle that somehow.....
while (item.Read())
{
Commands cmd = new Commands
{
cID = item.GetInt32(0),
cName = item.GetString(1),
cType = item.GetInt32(2),
msgID = item.GetInt32(3)
};
// store all those "Commands" retrieved into a list or something and return them
}
}

Categories