C#, Winform, Sql Server and Config file - c#

I have a C# winform app named xyz.exe. It operates using xyz.config file. The config file is a plain text file and in it I put my settings I need to run my app , such as how many times it has to iterate, what files to read, what are the default values etc etc. It works just fine. All is working OK. Today I started to work on some enhancement request, I need to make a connection to a sql server database and retrieve some information. Very straight forward.
If I run debug (F5) all is working OK. But if I run it from command prompt by typing xyz.exe it throws exception "The type initializer for 'System.Data.SqlClient.SqlConnectionFactory' threw an exception." and it points to the connection section. if I rename xyz.config to something else , the exception went away. if I create a blank App.config (this will generate xyz.exe.config), the exception went away.
What is going on? Can anybody explain this to me and what are the possible solutions, options, best solution? is is possible to make the app to not looking for xyz.config and xyz.exe.config w/o throwing exception. It was ok before I introduce connection to db.
SqlConnection connection = new SqlConnection(
"user id=xx;" +
"password=xx;" +
"server=xx;" +
"database=xx; " +
"connection timeout=xx");
try
{
connection.Open();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from xx",
connection);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader["xx"].ToString());
Console.WriteLine(myReader["xx"].ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
connection.Close();

Config files should be named <exename>.exe.config, e.g. if your exe name is xyz.exe, its config file name should be xyz.exe.config.
If you want to use non-standard names, you have to read config files manually.

Related

C#, MAS-90, Attempted to read or write protected memory error on OdbcDataAdapter.Fill(dataTable)

I am writing a Windows Forms application that needs to query 2 fields from a MAS-90 database. For this we use the MAS 90 32-bit ODBC Driver by ProvideX called SOTAMAS90. Here is the code I use to retrieve a DataTable from the MAS-90 database.
public static DataTable getDatatable(string qry)
{
DataTable dt = new DataTable();
using (OdbcConnection conn = new OdbcConnection(GetSQLConnection()))
{
try
{
OdbcCommand cmd = new OdbcCommand(qry, conn);
cmd.CommandType = CommandType.Text;
conn.Open();
OdbcDataAdapter adpt = new OdbcDataAdapter(cmd);
adpt.Fill(dt);
cmd.Dispose();
conn.Close();
conn.Dispose();
}
catch (OdbcException e) { conn.Close(); }
catch (AccessViolationException ae) { conn.Close(); }
catch (UnauthorizedAccessException ue) { conn.Close(); }
}
return dt;
}
On line adpt.Fill(dt) I get the following exception:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
This was working just fine yesterday. Today Visual Studio is telling me that this is an Unhandled AccessViolationException even though you can clearly see the try/catches. I had to add <legacyCorruptedStateExceptionsPolicy enabled="true"/> to my config file just for the exception to be caught in the try/catch.
The other strange thing is I am able to connect to the database and run the same exact query (which is just selecting 2 fields from a table) using the ODBC Query Tool by Jaime De Los Hoyos M. (Available here)
Any help at resolving this issue is greatly appreciated. Please let me know if you need additional information.
I also wanted to add that I have tried:
Targeting x86 in my app as the Driver is 32-bit
Giving permissions to the directory where the database is stored
Restarting PC
Changing query to add parameters with cmd.Parameters.AddWithValue("#PARAM", "Value")
I was able to resolve my issue. The database was stored on a server to which my PC had a mapped drive to. For whatever reason, the mapping broke for the MAS 90 32-bit ODBC Driver. This was strange because I was still able to access the network drive's files via File Explorer and I was also able to query the table via the ODBC query tool I mentioned (which uses the same ODBC driver). I discovered this when I wanted to change the Database Directory field (seen below) and it kept telling me the path was invalid or inaccessible (even though it was accessing it for the ODBC query tool).
Anyway, I remapped the network drive, then deleted and recreated the SOTAMAS90 DSN and it worked again.

Insert integer value into SQL Server database from C#

I am trying to insert an integer value into a SQL Server database as below when I run the program there are no any errors, but the table doesn't get updated with values. I have searched on the internet and I am doing the same can anyone help to find what I am doing wrong.
Note: I already defined "connectionString" as a string on the form class
private void btnUpdate_Click(object sender, EventArgs e)
{
int totalincome=600;
int totaldeductions = 10;
connectionString = ConfigurationManager.ConnectionStrings["BudgetApp.Properties.Settings.MainDataBaseConnectionString"].ConnectionString;
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("INSERT INTO Totals(TotalIncome, TotalDeductions) VALUES (#TotalIncome, #TotalDeductions)", con);
cmd.Parameters.AddWithValue("#TotalIncome", totalincome);
cmd.Parameters.AddWithValue("#TotalDeductions", totaldeductions);
cmd.ExecuteNonQuery();
MessageBox.Show("Done !!");
}
The whole AttachDbFileName= approach is flawed - at best! When running your app in Visual Studio, it will be copying around the .mdf file (from your App_Data directory to the output directory - typically .\bin\debug - where you app runs) and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the myConnection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The real solution in my opinion would be to
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. MainDataBase)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\\SQLEXPRESS;Database=MainDataBase;Integrated Security=True
and everything else is exactly the same as before...
Also see Aaron Bertrand's excellent blog post Bad habits to kick: using AttachDbFileName for more background info.
Code Seems correct,Perhaps you are checking the wrong DB?. I would add a Try/catch for exceptions. And remember to close connection after executing query. Regards
check your database column datatype,use try catch.
and try to replace cmd.Parameters.AddWithValue("#TotalIncome", totalincome); to cmd.Parameters.Add("#Number", SqlDbType.Int).Value = totalincome;
try
{
int totalincome=600;
int totaldeductions = 10;
connectionString = ConfigurationManager.ConnectionStrings["BudgetApp.Properties.Settings.MainDataBaseConnectionString"].ConnectionString;
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand(#"INSERT INTO Totals(TotalIncome, TotalDeductions) VALUES (#TotalIncome, #TotalDeductions)", con);
cmd.Parameters.Add("#Number", SqlDbType.Int).Value = totalincome;
cmd.Parameters.Add("#Number", SqlDbType.Int).Value = totaldeductions;
//cmd.Parameters.AddWithValue("#TotalIncome", totalincome);
//cmd.Parameters.AddWithValue("#TotalDeductions", totaldeductions);
cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}

Why session timeouts after OledbConnection open

i am calling the OledbConnection to Microsoft Access Database. there is no issue calling the method and also retrieves necessary data.
i dont know after that method the session timeouts automatically. and goes to login page. why?
i have lost entire day debugging and finding the issue.
string strQuery = "select count(LOC1) as LOC1 from shrmwise";
DataTable dt = new DataTable();
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand(strQuery, connection))
{
try
{
OleDbDataReader reader = command.ExecuteReader();
dt.Load(reader);
reader.Close();
}
catch (Exception ex)
{
throw ex;
//Console.WriteLine(ex.Message);
}
finally
{
connection.Close();
}
return dt;
}
}
Edited
Does not timeout if the above method call is commented.
it does not timeout on localhost, but on live server.
my connectionString as follows
string connectionString =
#"Provider=Microsoft.Jet.OLEDB.4.0;" +
#"Data Source=E:\Data\MyDatabase.mdb;" +
#"User Id=;Password=;";
Usually in a IIS/ASP.NET environment the application runs with MEDIUM TRUST settings and not with FULL TRUST. This means that your code cannot access any part of the file system that resides outside the root of your site.
To resolve the problem in which applications need a place where they can read and write without worrying about too much security restrictions a convention has been adopted.
The convention is to have a subfolder of the site root called APP_DATA where the user (IUSR) under which the ASP.NET service runs your application has Read/Write permissions. Here you can place your database or other read/write files. Create subfolder to store different type of documents and so on.
So your problem can be solved just following the convention and moving the database in that folder. Or, after verifying the security consequences of such move, force your site to run in FULL TRUST.
Of course if you have to manually create the APP_DATA folder be sure to also set the correct permissions for the IIS user.

Local Database won't show my programmaticaly added table

I will go at a c# contest and I will need to work with databases offline, and they should work on every PC, so if someone copies my project and runs my program, everything will work the same.
I created a Local Database with Add - New Item and made my database.
My code
private void Form1_Load(object sender, EventArgs e)
{
SqlCeConnection con = new SqlCeConnection(Properties.Settings.Default.bazalocalaConnectionString);
con.Open();
SqlCeCommand com = new SqlCeCommand("select * from Tabela",con);
SqlCeDataReader r = com.ExecuteReader();
while (r.Read())
{
MessageBox.Show(r["nume"].ToString());
}
com = new SqlCeCommand("create table taby(id int identity(1,1) primary key,nume nvarchar(10),prenume nvarchar(10) )", con);
com.ExecuteNonQuery();
con.Close();
}
The problem i have is, that after I create my table, and close the program, my new table won't be there in my server explorer.. why is that?
Did i Did something wrong?
And if I work like this, will it work on every PC?
My connection string is auto generated by visual studio when I create my local database and it is
Data Source=|DataDirectory|\bazalocala.sdf
When you use |DataDirectory| and compile the program in Visual Studio, the Visual studio creates a temp database in the Debug folder which is different from your original database. That is why the added table doesn't show up in there, instead of |DataDirectory| use the actual address.
The substitution string |DataDirectory| is replaced by the directory where your program runs.
During a Visual Studio debugging session this directory is BIN\DEBUG (or x86 variant).
So your table is added in a database located in BIN\DEBUG folder, while your server explorer window has a connection that points to a database located in the project folder.
You could try to add another connection that points to the database in the BIN\DEBUG folder and you will be able to see your table.
If you run your program outside VS then you don't have this problem.
To complicate further the matter there is the property Copy to output directory for your SDF file. If this property is set to Copy Always, then every time you start a debug session your SDF file is copied from your project folder to the BIN\DEBUG folder effectively overwriting the file and the change you have made in the previous debug session. You should change this property to Copy if Newer
you can try like this
try
{
SqlCeConnection con = new SqlCeConnection(Properties.Settings.Default.bazalocalaConnectionString);
con.Open();
//
// The following code uses an SqlCommand based on the SqlConnection.
//
using (SqlCeCommandcommand = new SqlCeCommand("CREATE TABLE taby(id int identity(1,1) primary key,nume nvarchar(10),prenume nvarchar(10) );", con))
{
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
SqlCeConnection con = new SqlCeConnection("Data Source=K:/PROJECT LOCATION/Database1.sdf");
con.Open();
string x = "insert into TABLE(your columns) values (what values you want)";
SqlCeCommand cmd = new SqlCeCommand(x, con);
try
{
cmd.ExecuteNonQuery();
}
catch
{
MessageBox.Show(" Something is wrong","ERROR!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
con.Close();
I created a connection and gave it the full location of the database, NOT the one from the bin/debug. Then i opened the connection and wrote the string x to save that data in my database. I created a new command which i tested in a try-catch clause and finally i closed the connection.

Try/Catch in MSI Installer Script

I have a Windows Installer prompting a user for MySQL information (server, port, username, password) and would like to make sure the parameters are correct prior to completing the setup.
I have have an Installer project with Custom Actions linked to the Installer Class and am doing my error checking there in the "Install" method. My error occurs at the catch() portion.
Any suggestions or comments greatly appreciated.
Edit: When I hit [Next] the installer installs the application and then prompts the MessageBox (if there's an error) but completes the installation. I was hoping for it to Rollback and bring up the previous screen.
Edit2: The exception caught from MySqlException is: "Unable to connect any of the specified MySQL hosts," which is correct, but the installer does not return/roll back.
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
// parameters from installer
// generate connection string conStr
MySqlConnection conn = new MySqlConnection(conStr);
MySqlCommand cmd = new MySqlCommand();
// open connection and create database
try
{
conn.Open();
cmd.Connection = conn;
// create database
// create table
// insert values to test
}
catch (MySqlException ex)
{
//I would like this to go back to the prior page
//where it asks for user input
MessageBox.Show("There was a problem connecting to the database.");
this.Rollback(stateSaver); // not working?
}
// close connection
conn.Close();
}
To force a rollback of your current installation you can rethrow the exception. you did just display in your messagebox.

Categories