Session variables being broken by an unrelated method - c#

I have a problem that is completely boggling me as it makes absolutely no sense. Ok, as I understand and have used in the past, to pass variables from one page to another via session, you simply say
Session["variableName"] = value;
Then to use it in the receiving page, it something like:
string container = Session["variableName"].ToString();
Right? Dandy. In my code (at least this particular application, anyway), I'm find that I can't set any session variables if I have a method in my page_load of the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
Session.Add("values", "It Worked");
LoadAvailableItems();
}
This will cause the application to not pass the variable to the next page. However, if I remove the LoadAvailableItems() method, it will work just fine. So now you'll ask me "ok, so show us whats inside of that method". It is just a test connection to run dummy data for a control:
//test connection DELETE ME
string connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
+ Server.MapPath("App_Code/temp/cokeDb.mdb") + ";Persist Security Info=False;";
OleDbConnection conn = new OleDbConnection(connString);
string sql = "select docNum, docName from lut_docs order by docNum";
OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
DataSet ds = new DataSet();
conn.Open();
da.Fill(ds);
conn.Close();
cblstAvailableItems.DataSource = ds;
cblstAvailableItems.DataTextField = "docName";
cblstAvailableItems.DataValueField = "docNum";
cblstAvailableItems.DataBind();
//end test connection
From what I was able to narrow it down to through commenting out blocks and running the application, I think it is related to this block:
conn.Open();
da.Fill(ds);
conn.Close();
Now WHY this is causing a problem, I do not understand in the slightest. If someone could explain this to me, I may refrain from putting my head through a wall.

Related

How to use a database connection class in my entire application

I have created a class for the MS Access database connection. It works fine on the majority of the forms within my Winforms app. However, I have a form where the user can add, edit or delete information from the database. I've constructed that part using a string, but when I remove the long database connection string I had there before and replace it with the class I created it throws an exception.
I've tried changing the code by removing the string, but I want to use the string method.
This is the code I have for the delete button click event
string con = (#"Provider = Microsoft.ACE.OLEDB.12.0; Data Source =C:\Users\folder\Desktop\ApplicationFolder\AppName\bin\Debug\DataBase\DatabaseName.accdb");
string Query = "delete from Employees2 where EmployeeName = '" +
this.txtAdminFEmployee.Text + "' ; ";
OleDbConnection ConnectionString = new OleDbConnection(con);
OleDbCommand command = new OleDbCommand(Query, ConnectionString);
OleDbDataReader reader;
try
{
ConnectionString.Open();
reader = command.ExecuteReader();
DialogResult result = MessageBox.Show("Employee Deleted Successfully",
"Information",
MessageBoxButtons.OK, MessageBoxIcon.Information);
while (reader.Read())
{
}
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
ConnectionString.Close();
This is the database class I created
using System.Data.OleDb;
namespace AppName
{
class OledbConnect
{
public OleDbConnection con;
public void Connection()
{
con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\DatabaseName.accdb");
}
}
}
I need to know how to use the database class in that string. I've tried different ways but nothing works. I am still new to c# and Google is not really returning anything I can use. Thanks
Your initial code works, but confusion is evident in the naming of variables.
string con = #"Provider = Microsoft.ACE.OLEDB.12.0; Data Source =C:\Users\folder\Desktop\ApplicationFolder\AppName\bin\Debug\DataBase\DatabaseName.accdb";
(I've taken the un-needed parentheses off the declaration; it's just a string.)
Calling that string 'con' is a bit confusing. I'd call it 'connectionString', or maybe 'cs' for short.
OleDbConnection ConnectionString = new OleDbConnection(con);
OleDbCommand command = new OleDbCommand(Query, ConnectionString);
OK, so you correctly create an OleDbConnection, passing the connection string (con) to its constructor. This is good. But you confusingly call it ConnectionString. It isn't the connection string; it's the connection, and your code thereafter uses it correctly.
So that works. Confusing for a human to read because of the mis-naming of variables, but the compiler doesn't care what their names are - it knows very well that ConectionString is an OleDbConnection and doesn't feel any of the cognitive dissonance that I do when I look at it.
If you rename the variables in the original code as I've suggested, and then copy that code into your class (BTW, I'd just call it DbConnection; it's current name is very close to another class name which might also be confusing), paying attention to what each statement does and what each variable represents then you should be good to go.

conversion failed varchar to int

Below is the code for combo box selected value change. It is supposed to pick up a value from DB and display it in a text box.
protected void cmbPujaName_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection con2 = null;
con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["SRKBSDB"].ConnectionString);
SqlDataAdapter pamt = new SqlDataAdapter("select Amount from PoojaDietyMaster where PoojaName =" + cmbPujaName.SelectedValue, con2);
DataSet pamtds = new DataSet();
pamt.Fill(pamtds); ......... Error shown here...........
txtAmount.Text = pamtds.Tables[0].Rows[0]["Amount"].ToString();
}
You're missing quotes but... do not do that like this. This way is like leaving your door wide open and invite thieves inside for a tea party. Or SQL Injection attack, inviting hackers to steal your whole database and/or server and take full control over it.
Have such code instead:
SqlDataAdapter pamt = new SqlDataAdapter("select Amount from PoojaDietyMaster where PoojaName = #name", con2);
pamt.SelectCommand.Parameters.AddWithValue("#name", cmbPujaName.SelectedValue);
DataSet pamtds = new DataSet();
pamt.Fill(pamtds);
This way you won't have to mess around with quotes, plus you're better protected against hackers.
It's a better practice to write a query using SqlCommand parameters by mentioning proper datatype to avoid sql injection attacks. Try to handle null values as well.
SqlDataAdapter pamt = new SqlDataAdapter("select Isnull(Amount,0.0) Amount from PoojaDietyMaster where PoojaName = #name", con2);
pamt.SelectCommand.Parameters.Add("#name",SqlDbType.VarChar).Value = cmbPujaName.SelectedValue.tostring();
DataSet pamtds = new DataSet();
pamt.Fill(pamtds);

How to display data in gridview from MS Access?

I want to display information of user stored in a MS Access database. The user enters his userid and on clicking a button following function is called. But no data is being displayed. What am I doing wrong ?
System.Data.OleDb.OleDbConnection con;
System.Data.OleDb.OleDbDataAdapter da;
protected void Button1_Click(object sender, EventArgs e)
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
string sql = "SELECT * From Leave where userid="+Textbox1.Text;
da = new System.Data.OleDb.OleDbDataAdapter(sql, con);
DataTable t = new DataTable();
da.Fill(t);
GridView1.DataSource = t;
con.Close();
}
You need to call GridView1.DataBind()
GridView1.DataSource = t;
GridView1.DataBind();
Just a side-note, it is good practice to wrap your connection with using
using(con = new System.Data.OleDb.OleDbConnection())
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
...
...
}
This ensures your connection is properly disposed after use
You should use bind function:
protected void Button1_Click(object sender, EventArgs e)
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
string sql = "SELECT * From Leave where userid="+Textbox1.Text;
da = new System.Data.OleDb.OleDbDataAdapter(sql, con);
DataTable t = new DataTable();
da.Fill(t);
GridView1.DataSource = t;
GridView1.DataBind();
con.Close();
}
First off, please, please please don't concatenate your WHERE parameters in your SQL. Use Parameters. Second, Add a "using System.Data.OleDb" statement at the top of your module, so that you are not having to type things like:
System.Data.OleDb.OleDbDataAdapter
Over and over again.
Try the following code. Personally, when I have to work with data tables and such, I prefer to avoid all the DataAdapter nonsense, and keep it as simple as possible.
Note in the code below:
the "using" blocks. These place the variables created within them inside their own scope, and take care of disposal and such for you.
I used an OleDb Parameter instead of concatenating criteria. This is a much safer way to do things, and creates much cleaner and more readable code as well, especially in cases where you have several criteria in your WHERE clause.
I assume your UserID input is a string, since you are grabbing the value from a Textbox. If it is in fact an int value (such as an auto-incrementing id in MS Access) you will need to use an int data type instead. You may have to mess with it a little. When you are still figuring this stuff out, it can be a bit painful. However, using parameters increases security and maintainability.
Once you have obtained a data table as the return from the MyUsers method, you should be able to simply set the data source of your Gridview. If you have difficulties still, do as Steve suggests and check the Autogenerate columns property in the designer, or set it in code.
Not that I have moved the connection string to the project Properties/Settings. You should find this in the solution designer. Place your connection string there, in one spot, and you can obtain it from anywhere in your code. If you later change the connection string (such as moving your Db to another computer, server share, etc) you need only change it in one place.
SAMPLE CODE:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb; // put this here, and stop writing long namespaces inline
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Where possible, move code out of specific event handlers
// into methods which can be re-used from other client code.
// Here, I pulled the actual data access out into separate methods,
// and simply call it from the event handler:
this.LoadGridView(textBox1.Text);
}
private void LoadGridView(string UserID)
{
// Now we can load the gridview from other places in our
// code if needed:
this.dataGridView1.DataSource = this.MyUsers(UserID);
}
private DataTable MyUsers(string UserID)
{
var dt = new DataTable();
// Use a SQL Paramenter instead of concatenating criteria:
string SQL = "SELECT * FROM Leave WHERE userid = #UserID";
// The "using" statement limits the scope of the connection and command variables, and handles disposal
// of resources. Also note, the connection string is obtained from the project properties file:
using(OleDbConnection cn = new OleDbConnection(Properties.Settings.Default.MyConnectionString))
{
using (var cmd = new OleDbCommand(SQL, cn))
{
// For simpler things, you can use the "AddWithValue" method to initialize a new parameter,
// add it to the Parameters collection of the OleDBCommand object, and set the value:
cmd.Parameters.AddWithValue("#UserID", UserID);
// Get in, get out, get done:
cn.Open();
dt.Load(cmd.ExecuteReader());
cn.Close();
}
}
return dt;
}
}
}
Hope that helps. It's not how everyone might do it, but I have found it provides maximum flexibility, when you must work with MS Access.

Issues querying Access '07 database in C#

I'm doing a .NET unit as part of my studies. I've only just started, with a lecturer that as kinda failed to give me the most solid foundation with .NET, so excuse the noobishness.
I'm making a pretty simple and generic database-driven application. I'm using C# and I'm accessing a Microsoft Access 2007 database.
I've put the database-ish stuff in its own class with the methods just spitting out OleDbDataAdapters that I use for committing. I feed any methods which preform a query a DataSet object from the main program, which is where I'm keeping the data (multiple tables in the db).
I've made a very generic private method that I use to perform SQL SELECT queries and have some public methods wrapping that method to get products, orders.etc (it's a generic retail database).
The generic method uses a separate Connect method to actually make the connection, and it is as follows:
private static OleDbConnection Connect()
{
OleDbConnection conn = new OleDbConnection(
#"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Temp\db.accdb");
return conn;
}
The generic method is as follows:
private static OleDbDataAdapter GenericSelectQuery(
DataSet ds, string namedTable, String selectString)
{
OleDbCommand oleCommand = new OleDbCommand();
OleDbConnection conn = Connect();
oleCommand.CommandText = selectString;
oleCommand.Connection = conn;
oleCommand.CommandType = CommandType.Text;
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = oleCommand;
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.Fill(ds, namedTable);
return adapter;
}
The wrapper methods just pass along the DataSet that they received from the main program, the namedtable string is the name of the table in the dataset, and you pass in the query you wish to make.
It doesn't matter which query I give it (even something simple like SELECT * FROM TableName) I still get thrown an OleDbException, stating that there was en error with the FROM clause of the query. I've just resorted to building the queries with Access, but there's still no use. Obviously there's something wrong with my code, which wouldn't actually surprise me.
Here are some wrapper methods I'm using.
public static OleDbDataAdapter GetOrderLines(DataSet ds)
{
OleDbDataAdapter adapter = GenericSelectQuery(
ds, "orderlines", "SELECT OrderLine.* FROM OrderLine;");
return adapter;
}
They all look the same, it's just the SQL that changes.
Have you tried something more simple to see if you have connectivity to the table you are looking for. Something like
DataSet ds = new DataSet();
using (OleDbConnection myConnection = new OleDbConnection
(#"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Temp\db.accdb"))
{
myConnection.Open();
OleDbDataAdapter myAdapter = new OleDbDataAdapter("SELECT OrderLine.* FROM OrderLine;, myConnection);
myAdapter.TableMappings.Add("Table", "TestTable");
myAdapter.Fill(ds);
}
Then from there check to see if stuff is in ds with
ds.Tables[0].Rows.Count()
This will actually show you if you are hitting the DB and getting results. From there you can make it more elegant
Square brackets seem to have fixed the problem. Turns out I was using a keyword. Hmph.

Page Life Cycle, does db connection go in Page_Load

Currently I have The following code:
void Page_Load(object sender, System.EventArgs e)
{
string connectionString = "server=abc;database=abc;uid=abc;pwd=1234";
SqlConnection mySqlConnection = new SqlConnection(connectionString);
string procedureString = "Callin_Insert";
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText = procedureString;
mySqlCommand.CommandType = CommandType.StoredProcedure;
mySqlCommand.Parameters.Add("#LVDate", SqlDbType.DateTime).Value = DateTime.Now;
mySqlCommand.Parameters.Add("#LVTime", SqlDbType.DateTime).Value = DateTime.Now;
mySqlCommand.Parameters.Add("#CuID", SqlDbType.Int).Value = CustID;
mySqlCommand.Parameters.Add("#Type", SqlDbType.Int).Value = Keypress;
mySqlConnection.Open();
mySqlCommand.ExecuteNonQuery();
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter();
mySqlDataAdapter.SelectCommand = mySqlCommand;
mySqlConnection.Close();
}
Basically, I am opening a connection to the Database during the page_load. I am also closing that connection in page_load. Part of my problem is that the CustID & Keypress are not getting passed, because they occur later in the page life cycle. What is the best way to open the connection, get the 2 variables (when I they are entered by the user), pass them to the database, and close the connection.
Somethings I have tried is running it _OnLoad. But this didn't work either.
Any thoughts or suggestion, are greatly appreciated.
First of SqlConnection is of IDisposible interface means it is much safer to wrap your code with using statement like this.
string connectionString = "server=abc;database=abc;uid=abc;pwd=1234";
using (SqlConnection mySqlConnection = new SqlConnection(connectionString))
{
string procedureString = "Callin_Insert";
SqlCommand mySqlCommand = new SqlCommand(procedureString, mySqlConnection);
mySqlCommand.CommandType = CommandType.StoredProcedure;
mySqlCommand.Parameters.Add("#LVDate", SqlDbType.DateTime).Value = DateTime.Now;
mySqlCommand.Parameters.Add("#LVTime", SqlDbType.DateTime).Value = DateTime.Now;
mySqlCommand.Parameters.Add("#CuID", SqlDbType.Int).Value = CustID;
mySqlCommand.Parameters.Add("#Type", SqlDbType.Int).Value = Keypress;
mySqlConnection.Open();
mySqlCommand.ExecuteNonQuery();
//i have no idea what does this mean, data adapter is for filling Datasets and DataTables
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter();
mySqlDataAdapter.SelectCommand = mySqlCommand;
}
Second of all i offer you to use SqlDataSourceObject control which will make much easier to work with cases like yours.
It will know how to deal with Page.IsPostBack that you haven't implemented but should, paging and other stuff you need.
Think there are a few problems here... first of all why are you running your query and then passing it to a data adapter? The data adapter will run the select command when queried.
I suggest creating a SqlDataSource on your aspx page (not code behind) and bind your control to it. Then hook up the Selecting event and in there populate your parameters. That should happen later in the page lifecycle so your parameter values will then be set.

Categories