can't connect to sql azure database using monotouch - sql

I'm working on a iphone project using c# and monotouch.
I need to use an SQL Azure database.
My problem is that I cant seem to get connected using monotouch.
I can make the code below work fine in a native console application built on a windows 8 machine using visual studio 2012.
But, when I try to port it over to an imac and use monodevelop/monotouch my iphone app crashes.
The error I get is:
System.NotImplementedException: SSL encryption for data sent between client and server is not implemented.
I google around a bit and found a bug report that seems to describe my exact issue here. I noticed its almost two years old so i'm not sure if this would still be unimplemented.
So, I tried changing the value of StringBuilder.Encrypt = true; to false.
But, it still crashes and I get the error:
Mono.Data.Tds.Protocol.TdsInternalException: Server closed the connection. ---> System.IO.IOException: Connection lost
in either case the app crashes when conn.Open(); is called.
I'm pretty stuck, and I don't have a choice but to use SQL Azure.
So, if anyone could suggest a solution or work around for my issue, I'd appreciate it greatly.
thanks in advance!
string userName = "<username>#<myservername>";
string password = "<password>";
string dataSource = "<myservername>.database.windows.net";
string databaseName = "<dbname>";
SqlConnectionStringBuilder connStringBuilder;
connStringBuilder = new SqlConnectionStringBuilder();
connStringBuilder.DataSource = dataSource;
connStringBuilder.InitialCatalog = databaseName;
connStringBuilder.Encrypt = true;
connStringBuilder.TrustServerCertificate = false;
connStringBuilder.UserID = userName;
connStringBuilder.Password = password;
using (SqlConnection conn = new SqlConnection (connStringBuilder.ToString())) {
conn.Open();
using (IDbCommand dbcmd = conn.CreateCommand()){
string sql = "Select client_username from dbo.client;";
dbcmd.CommandText = sql;
using (IDataReader reader = dbcmd.ExecuteReader()){
while( reader.Read() ){
string username = (string) reader["client_username"];
}
}
}
}

SSL for SqlConnection class is not implemented. See SqlConnection.cs
And as Azure requires an encrypted connection you'll have to do some workaround. For example you could create a web role and expose a web service which executes the SQL on your behalf.

try using a simple string as your connection string:
connStr = "Server=tcp:<server_here>.database.windows.net,1433;Database=<db_name_here>;Trusted_Connection=False;Encrypt=True;TrustServerCertificate=False;UserID=<user_name_here>#<server_name_here>;Password=<password_here>";
using (SqlConnection conn = new SqlConnection (connStr)) {
conn.Open();
using (IDbCommand dbcmd = conn.CreateCommand()){
string sql = "Select client_username from dbo.client;";
dbcmd.CommandText = sql;
using (IDataReader reader = dbcmd.ExecuteReader()){
while( reader.Read() ){
string username = (string) reader["client_username"];
}
}
}
}
Note differences - use Server, Database. Once you get the connection string correct, you can use try the ConnectionStringBuilder and see if you get the exact same output. BUt its easier to just use a string if you have one that works.

Related

LogIn form, SQL exception

I'm trying to make a simple program that has a log-in part, with a local database just for testing.And i keep getting an error when I try to open the connection to the SQL database.
private void logInButton_Click(object sender, EventArgs e)
{
MainMenu openMainMenu = new MainMenu();
SqlConnection sqlcon = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C: \Users\Nea Florin\Desktop\PlatformaTestare\PlatformaTestare\Server.mdf;Integrated Security=True;Connect Timeout=30");
sqlcon.Open();
SqlCommand cmd = new SqlCommand("Select * from Table Where username ='" + usernameTextBox.Text + "' and password = '" + passwrodTextBox.Text + "'");
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dtbl = new DataTable();
sda.Fill(dtbl);
if (dtbl.Rows.Count > 0)
{
openMainMenu.Show();
this.Hide();
}
else
MessageBox.Show("Wrong username or password!");
}
I get the error at sqlcon.Open();, and it is: "An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: An attempt to attach an auto-named database for file C: \Users\Nea Florin\Desktop\PlatformaTestare\PlatformaTestare\Server.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."
Well, the best advice I can give you is to google the error message. Keep in mind that if there is an error message it means that the problem is well known an as such it's a safe bet that someone have encountered it before you and managed to solve it. The first 4 results of this search are on stackoverflow and at least two of them have accepted answers, so I believe a little reasearch would have saved you a long time.
This is the best advice because it streaches far beyond your current problem. I firmly believe that good searching skills is the most important and most powerfull tools of a sotfware developer. I can assure you, no matter how much time you are developing software, almost every exception you get, someone else have already solved and posted the solution somewhere, you only need to find it.
Now, as for the code it self - You have some major problems other then the exception you are asking about:
Concatenating strings into sql statements instead of using parameters expose your code to SQL injection attacks. This is a very serious threat that is extremely easy to fix.
Using insntances of classes that implements the IDisposable interface without properly disposing them may lead to memory leak. Read about the using statement and make it a habit to use it every time it's possible.
Exception handling. Currently, if your database can't be reached, you get an exception and your program crash. You should use a try...catch block anywhere you can't control in code to let your program end gracefuly instead. (Don't ever use try...catch for things you can do in code such as validate user input or checking division by zero - only for things that are beyon your control such as database availability.)
Having said all that, your code should look something like this:
private void logInButton_Click(object sender, EventArgs e)
{
using (var sqlcon = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|C:\Users\Nea Florin\Desktop\PlatformaTestare\PlatformaTestare\Server.mdf;Integrated Security=True;Connect Timeout=30"))
{
sqlcon.Open();
using (var cmd = new SqlCommand("Select 1 from Table Where username = #userName and password = #password"))
{
cmd.Parameters.Add("#userName", SqlDbType.NVarChar).Value = usernameTextBox.Text;
cmd.Parameters.Add("#password", SqlDbType.NVarChar).Value = passwrodTextBox.Text;
using (var dtbl = new DataTable())
{
using (var sda = new SqlDataAdapter(cmd))
{
sda.Fill(dtbl);
}
if (dtbl.Rows.Count > 0)
{
var openMainMenu = new MainMenu();
openMainMenu.Show();
this.Hide();
}
}
else
{
MessageBox.Show("Wrong username or password!");
}
}
}

Is it better to create Single or multiple SQL connection to execute same query multiple time?

I'm executing same command in every 2 seconds. I think following code creates multiple connections:
[System.Web.Services.WebMethod]
public static int getActivity()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString()))
{
connection.Open();
using (var cmd = new SqlCommand("SELECT TOP 1 ValueX FROM TABLE WHERE ID= 2 AND EVENTID = 2 ORDER BY DATE DESC", connection))
{
var x = cmd.ExecuteScalar();
int Result;
if (x != null)
{
Result = int.Parse(x.ToString());
Console.WriteLine("USER ACTIVITY : " + Result);
}
else
{
Result = -999;
}
connection.Close();
return Result;
}
}
}
If I call this method several time Does following code make multi connection Or single connection ?
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString()))
Can someone explain whether I need to modify this code or Is this good one ?
Thanks.
Since you are using the using statement clause so once you are done with the method the resources are freed and the connection is closed. So everytime when you call the same method a new connection will be made. When you are using the using clause then it is equivalent to the below code:
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
}
finally
{
if(connection != null)
((IDisposable)connection).Dispose();
}
Also note that you dont need to explicitly call the connection.Close(); in your method as using statement will take care of it.
Your method is fine, you just don't need connection.Close() as described by Rahul. Using statement when dealing with SQL objects is good practice.
What you should keep in mind, is that ADO.NET connection pooling, takes care of handling new objects referring to the same connection string, thus minimizing the time needed to open a connection.
More about connection pooling can be found Here

Cannot access existing table from WCF Code

try
{
string strSQLConnString = GetConnectionString();
using (SqlConnection myConnection = new SqlConnection(strSQLConnString))
{
SqlCommand myCommand = new SqlCommand("spFortesting", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("#Param1", varParam1);
myCommand.Parameters.AddWithValue("#Param2", varParam2);
myCommand.Parameters.AddWithValue("#Param3", varParam3);
myCommand.Parameters.AddWithValue("#Param4", varParam4);
myConnection.Open();
using (SqlDataReader myReader = myCommand.ExecuteReader())
{
dt = new DataTable();
if (myReader.HasRows)
{
dt.Load(myReader);
}
myReader.Close();
}
myConnection.Close();
}
}
catch (Exception ex)
{
throw ex;
}
I am getting exception like
"The exception message is 'Could not find stored procedure 'spFortesting'."
All other existing Stored Procs are accessed correctly.
Connection string is common for all other SQL calls in the application.
'spFortesting' is newly created StoredProc.
owner is 'dbo' I tried with dbo.spname as well
While I can access the Stored Proc and Tables which are newly created using SQL Mgmt Studio and the same credentials as in web.config, but not thru the code.
What could have been wrong.
Thanks in Advance,
Amit
My mistake! when i watched it very closely I found that connection strings are not matching, the connectionstring was being picked up from the other similar sounding virtual directory. System.Configuration.Configuration rootWebConfig =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(#"\AppName");
and my appname on the deployed server was AppNameNew for some unkown reasons, since ages. With the name AppName there was another virtual folder and its web.config was pointing towards different database.
Sorry for the inconvenience caused if any.
Cheers!!!
and a Happy new year

One-Way sync of data without changing schema of source database

I Have a database that we want to partially sync data out of into another database (on Azure).
I have been looking at Sync Framework 2.1 and believe it can solve the problem, however i cannot figure it out from the online documentation.
We have the restraint that we cannot change the schema of the database however we are on SQL 2008 R2 which means that we can use track changes.
I am looking for some advise on how this might be achieved.
currently i have a SyncOrchestrator
var orch = new SyncOrchestrator
{
LocalProvider = new SampleServerSyncProvider(),
RemoteProvider = new SampleClientSymcProvider(),
Direction = SyncDirectionOrder.Upload
};
and then a sync provider
public class SampleServerSyncProvider : DbServerSyncProvider
{
private String SQLLocalConnection = "valid connection string";
public SampleServerSyncProvider()
{
SqlConnection serverConn = new SqlConnection(SQLLocalConnection);
Connection = serverConn;
Connection.Open();
var cmTableSyncAdapter = new SqlSyncAdapterBuilder
{
Connection = serverConn,
ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking,
SyncDirection = SyncDirection.Bidirectional,
TableName = "my table"
};
SyncAdapters.Add(cmTableSyncAdapter.ToSyncAdapter());
}
}
Currently i am getting an error that talks about initializing the connection. But I cannot find an initialize method on any of the objects
System.InvalidOperationException : Cannot create a SyncAdapter for table 'My table' by using
SqlSyncAdapterBuilder because the connection to the server has not yet
been initialized. Initialize the Connection property of the
SqlSyncAdapterBuilder before you call any of the SqlSyncAdapterBuilder
methods
SQL Change Tracking is only supported on the older offline providers (SqlClientSyncProvider/DbServerSyncProvider/SyncAgent). The newer providers you're trying to use (SqlSyncProvider/SyncOrchestrator) requires a custom change tracking. You cannot mix and match the database sync providers.
have you looked at using SSIS instead?

storing pdf files using filestream on file system

I am first time trying to use filestream to store pdf files on file system using varbinary(MAX) column type of DB.
I have followed following steps.
enabled filestream feature on SQL server 2008 R2.
Create a filegroup for BLOB storage
created table with blob column of type varbinary(max)
Now, I want to use file upload control to select file and when click on upload button it should save the pdf file. Also, how to retrieve the file?
I have tried following code
protected void btnFSupload_Click(object sender, EventArgs e)
{
SqlConnection cn = null;
SqlTransaction tx = null;
SqlCommand cmd = null;
SqlCommand cmd2 = null;
bool bCommit = false;
try
{
// read in the file to be saved as a blob in the database
FileStream input = new FileStream(#"D:\swami.pdf", FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[(int)input.Length];
input.Read(buffer, 0, buffer.Length);
cn = new SqlConnection("server=at-hetal01\\sqlexpress;Initial Catalog=practice;Integrated Security=true;");
cn.Open();
tx = cn.BeginTransaction();
cmd = new SqlCommand("dbo.stp_AddBLOB", cn, tx);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlDataReader r = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
r.Read();
string id = r[0].ToString();
string path = r[1].ToString();
r.Close();
// get the transaction context
cmd2 = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", cn, tx);
Object obj = cmd2.ExecuteScalar();
byte[] txCtx = (byte[])obj;
// open the filestream to the blob
SafeFileHandle handle = OpenSqlFilestream(path,DESIRED_ACCESS_WRITE,SQL_FILESTREAM_OPEN_NO_FLAGS,txCtx,(UInt32)txCtx.Length,0);
// open a Filestream to write the blob
FileStream output = new FileStream(handle,FileAccess.Write,buffer.Length,false);
output.Write(buffer,0,buffer.Length);
output.Close();
if (handle != null && !handle.IsClosed)
handle.Close();
bCommit = true;
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
if (cn != null)
{
switch (bCommit)
{
case true:
tx.Commit();
break;
case false:
tx.Rollback();
break;
}
cn.Close();
}
}
}
Above code shows error as below
The operating system returned the error '0xc000003a({Path Not Found} The path %hs does not exist.)' while attempting 'NtCreateFile' on 'D:\DB\FS\d11132f8-c2a8-452d-ae0c-208164a550d7\beb8e1f1-8116-440b-870b-7cef4281a15d\0000001c-000000e4-010d'. The statement has been terminated.
So, any clue on this?
If you have altered your table using SSMS table designer, the FILESTEAM column attribute will be lost producing the path not found. Make sure the FILESTREAM attribute is set for the file field by running the follwoing statement in your database:
select SERVERPROPERTY('FilestreamShareName') as ShareName,
SERVERPROPERTY('FilestreamConfiguredLevel') as ConfiguredLevel,
SERVERPROPERTY('FilestreamEffectiveLevel') as EffectiveLevel
You'll need to alter the table via a script and NOT SSMS to tie your varchar(max)/filestream field to the FileGroup you should have already created.
When I ran into this issue, I found the answer on StackOverflow, but can't seem to find it again for the reference.
I know this is old, but for future reference:
We checked the SERVERPROPERTY values that #BMP suggested. They were configured correctly, so that didn't help.
However, we went ahead and turned OFF the windows file share part of the file streaming access. Once this was done, the error went away.
In our case it was a web app running on the exact same machine as the sql server which exhibited the problem. I'm not sure if the web app's app pool user didn't have access to the file share created by windows or not.
The details were:
Windows 2003 Server (x86)
IIS 6
SQL Server 2008 R2 Express
UPDATE: Apparently this worked for a few days. It's not working any more.