Issue with comparing data in sqldatareader to log in details C# (Newbie) - c#

I'm having an issue with an if statement in my code which for the life of me I can't figure out why the condition isn't coming back true.
private bool ValidationFunction(string UserName, string Password)
{
bool returnBool = false;
var strConnection = ConfigurationManager.ConnectionStrings["BankConnectionString"].ConnectionString;
SqlConnection sqlConnection = new SqlConnection(strConnection);
string query = "SELECT " + COLUMN_ID + ", " + COLUMN_MACHINEPIN + " FROM " + PERSON_TABLE + " WHERE " + COLUMN_ID + " = \'" + UserName + "\' AND " + COLUMN_MACHINEPIN + " = \'" + Password + "\'";
SqlCommand command = new SqlCommand(query, sqlConnection);
SqlDataReader rdr;
sqlConnection.Open();
rdr = command.ExecuteReader();
while(rdr.Read())
{
if (UserName == rdr["Id"].ToString() & Password == rdr["MachinePin"].ToString())
{
returnBool = true;
}
return returnBool;
}
rdr.Close();
return returnBool;
}
I have tried using both the name of the column and the constant I used in the query but neither works and I can't quite get it work. Any help would be appreciated
EDIT: Turns out that the data I was retrieving from the database had extra white space because I had used an nchar so I had to use the trim function.

You should use && not &.
& is a bit-wise "AND", meaning that it works on the bit level, whereas && is a logical "AND" meaning it works at boolean (true/false) level.
I'd also clean up your code a bit. By not parameterizing your inputs, you are opening yourself up to SQL Injection attacks.
You can also wrap your disposable objects in using blocks. It will make your code cleaner and more readable.
using (var conn = new SqlConnection("your connection"))
{
using (var cmd = new SqlCommand(sql, conn))
{
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
...
}
}
}

Try this:
var username = rdr["Id"].ToString()
var password = rdr["MachinePin"].ToString())
Debugger.Break();
At the debugger statement open up the immediate windows and manually type in the comparisons until you determine root cause.
UserName==username;
Password = password;
Debuging Tips
Do you know how to open the Immediate Window? Go to Debug/Windows/Immediate. It allows you to type in C# statement at the debug point.
No Data can be read
If rdr["Id"] cannot be read e.g InvalidOperation etc. Then you have one of the following issues:
Connection string never opened connection
Wrong Database/Table
Incorrect Field Name
Security failure.
You should check status codes for each of your steps, if you are not seeing anything then this is most likely a security issue because banks don't advertise what went wrong (makes sense don't tell hackers anything).
Security Issue
If it's security issue you have to drop down to wire level. Take a trace and look at the Return codes. The other side will Fin the session first. You should see a security layer handshake prior to open communications, if that handshake doesn't work the session is immediately terminated with no further detail.
Tracing
Wireshark is simple to use, quick to download and shows everything on the wire. Use Wireshark to further dive into things the application layer cannot see.

Try the below:
if ((UserName == (string)rdr["Id"]) && (Password == (string)rdr["MachinePin"]))
{
returnBool = true;
}

Related

Querying OLAP Cubes via ASHX Service

I'm using the following code to execute a query in C#:
// Create Connection String
AdomdConnection testConnection = new AdomdConnection("Data Source=*****;User ID=******;Provider=MSOLAP.6;Persist Security Info=True;Impersonation Level=Impersonate;Password=******");
// Test Open
testConnection.Open();
// Make Query
AdomdCommand cmd = new AdomdCommand(#"SELECT { [Measures].[Payment Amount] } ON COLUMNS,
{ [Charging Low Orgs].[Charging Division].[Charging Division] } ON ROWS
FROM [Payments]", testConnection);
AdomdDataReader dataReader = cmd.ExecuteReader();
// Close Connection
testConnection.Close();
And I keep getting this error on the cmd.ExecuteReader() call:
{"XML for Analysis parser: The CurrentCatalog XML/A property was not specified."}
The only literature that I could find that was relavent to this was that the query isn't resolving because impersonation wasn't set, but I specified that in the connection string.
Another article which I don't think is related, said to enable BAM on Excel, but I don't have that option in Excel, and I fail to see how that would make a difference for a web service.
Please help!
The following example includes a catalog parameter in the connection string:
static void Main(string[] args)
{
AdomdConnection conn = new AdomdConnection(
"Data Source=localhost;Catalog=Adventure Works DW Standard Edition");
conn.Open( );
string commandText = "SELECT {[Measures].[Sales Amount], " +
"[Measures].[Gross Profit Margin]} ON COLUMNS, " +
"{[Product].[Product Model Categories].[Category]} ON ROWS " +
"FROM [Adventure Works] " +
"WHERE ([Sales Territory Country].[United States])";
AdomdCommand cmd = new AdomdCommand(commandText, conn);
AdomdDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

Close SQL Connection on Form Close (C#)

I created a small application that queries a db2 database and returns information. I created a windows form that accepts input and returns the information from the query. My closing statement is a:
finally
{
conn.close();
}
I was curious -- does the connection (conn) actually close when I hit the little red box on the form? I searched the other questions here and the web but could not really find a definitive answer.
Here's the full try-catch-finally block (with some info obfuscated --> *****):
`try
{
conn.Open();
string queryString = String.Format("SELECT * " +
"FROM ***** " +
"WHERE USERPRF LIKE '%{0}%' " +
"ORDER BY TIMESTMP DESC " +
"FETCH FIRST 1 ROWS ONLY", userNameInput);
using (OdbcCommand com = new OdbcCommand(queryString, conn))
{
using (OdbcDataReader reader = com.ExecuteReader())
{
if (reader.Read())
{
string ***** = reader["*****"].ToString();
string ***** = reader["*****"].ToString();
string user = reader["USERPRF"].ToString();
string timeStamp = reader["TIMESTMP"].ToString();
listBox1.Items.Clear();
listBox1.Items.Add("Username: " + user);
listBox1.Items.Add("*****" + *****);
listBox1.Items.Add("*****: " + *****);
listBox1.Items.Add("Last Changed: " + timeStamp);
}
else
{
listBox1.Items.Clear();
listBox1.Items.Add("There was no data to return! Try again.");
}
}
}
}
catch (Exception ex)
{
string errorMessage = ex.Message;
}
finally
{
conn.Close();
}`
If the connection is owned by the application, then yes - it should close.
It is generally bad practice to leave a connection open for long duration's as it constitutes a security risk. (Someone could inject code into your application to reuse the open the connection, to do dodgy stuff)
using (SqlConnection cn = new SqlConnection(strConnectString))
{
// Stuff
}
I would make sure that you handle the onClosing event of your windows form, and tell it to dispose of the SqlConnection explicitly, or at least attempt to do so.
Better safe than sorry.
Note - I have heard some talk that SqlConnections can be shared in the SQLConnectionPool. If this is the case, you can modify your connection string to disable or enable ConnectionPooling.

C# OleDb Login Validation doesn't work

So basically I am creating a login system using C#.net and MS access.I am using a class to deal with all the connections but basically the username and password values are passed to the method in the connection class and I am trying to check the credentials from the text boxes against the database.
Problem is, when I use executenonquery it allows any credentials to be entered even if they are not in the database.
I am currently using ExecuteReader and checking whether the reader is returning true. Problem is it always returns false even when the credentials that are entered are present in the database. I have no idea what is wrong.
public static bool adminLoginIn(string user, string password) //method to allow the admin to log in to the admin panel
{
OleDbConnection myConnection = GetConnection(); //calls the connection method which returns database connection string
string myQuery = "SELECT * FROM Staff WHERE Username = '" + user + "' AND Password = '" + password + "'";
OleDbCommand myCommand = new OleDbCommand(myQuery, myConnection);
try
{
myConnection.Open(); //open the database connection
OleDbDataReader dr = myCommand.ExecuteReader();
if (dr.Read())
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
return false;
}
finally
{
myConnection.Close(); //close the database connection
}
}
If it's always returning false no matter what, checking your catch statement is a prime suspect: if your code is raising an exception you're swallowing it and returning false.
Remove the try/catch and replace it with a using (and apply it to the other IDisposables, too).

Error when using insert in access: Could not Update; currently locked

I have a WebService that updates my access table from some terminals (10).
When I try to update I get this error from the error log:
Could not Update; Currently locked
Some terminals succeed and some do not.
I update like this:
using (Conn = new OleDbConnection(Work_Connect))
{
Conn.Open();
foreach (DataRow R in ds.Tables["MyCount"].Rows)
{
U_ID = ID;
U_Bar = R["Bar"].ToString().Trim();
U_Qty = R["Qty"].ToString().Trim();
U_Des = R["Des"].ToString().Trim();
SQL = "INSERT INTO MyTbl(ID,Bar,Qty,Des)VALUES('";
SQL += Convert.ToInt32(ID) + "','" + U_Bar + "','" + Convert.ToDouble(U_Qty) + "','" + U_Des + "')";
OleDbCommand Cmd2 = new OleDbCommand(SQL, Conn);
Cmd2.CommandText = SQL;
Cmd2.ExecuteNonQuery();
}
}
GC.Collect();
return true;
MsAccess has serious drawbacks for multi-user update. The Jet engine is not a database server, and will manage concurrence based on file system locking. If your problem is with a web service, I'd move the update to the server part, and implement queuing of simultaneous requests there. Thus, only the server, one process, will have access to the Access data. The other option is to use a real database server that will do that work for you. SQL Server Express is the usual option because it's easy to integrate, it's free as in beer, and is solid.
Also, if your problem happens always from the same terminals, that is, some terminals can never update anything, check the file access rights of these terminals' users to the database file, the lock file, and the database and lock file directory. Write rights are required for all of them.
Suggestions:
Convert your query to a parameterized query to avoid any potential strangeness with quoting. (You are converting text to numbers and then enclosing them in single-quotes in the SQL statement. That makes no sense.)
Don't force garbage collection on each call. According to the MSDN article here: "It is possible to force garbage collection by calling Collect, but most of the time, this should be avoided because it may create performance issues."
Try something like this instead:
using (Conn = new OleDbConnection(Work_Connect))
{
Conn.Open();
foreach (DataRow R in ds.Tables["MyCount"].Rows)
{
U_ID = ID;
U_Bar = R["Bar"].ToString().Trim();
U_Qty = R["Qty"].ToString().Trim();
U_Des = R["Des"].ToString().Trim();
SQL = "INSERT INTO MyTbl (ID,Bar,Qty,Des) VALUES (?,?,?,?)";
using(OleDbCommand Cmd2 = new OleDbCommand(SQL, Conn))
{
// Cmd2.CommandText = SQL; redundant, the 'new' set the .CommandText
Cmd2.Parameters.AddWithValue("?", Convert.ToInt32(ID));
Cmd2.Parameters.AddWithValue("?", U_Bar);
Cmd2.Parameters.AddWithValue("?", Convert.ToDouble(U_Qty));
Cmd2.Parameters.AddWithValue("?", U_Des);
Cmd2.ExecuteNonQuery();
}
}
Conn.Close();
}
// GC.Collect(); // disabled for test purposes
return true;

Retrieve & update 20000 data records stops working

I am using the following code do get all data records from a MS SQL database and I try to update every single record. The code is used in a WebService. The issue is, that the code runs fine if I have 1000 data records but now I have 20000 data records an the code first returned with an timeout. Then I set the cmd.CommandTimeout to zero to have no timeout. Now when I invoke the function in the IE WebSvc the IE window is still blank and still try to load something but nothing happens. Only 150 datarecords are updated.
Do you have any idea where the issue might be ? Is the code not the best, so what should I change ?
Thank you very much!
WorldSignia
MyCode:
private string AddNewOrgBez()
{
try
{
SqlConnection sqlconn = new SqlConnection(this.connectionString);
SqlCommand cmd;
SqlDataReader reader;
sqlconn.Open();
cmd = new SqlCommand("SELECT * FROM dbo.mydata", sqlconn);
cmd.CommandTimeout = 0;
reader = cmd.ExecuteReader();
while (reader.Read())
{
// Felder holen
string okuerzel = reader["O_KURZ"].ToString();
string bezeichnung = reader["O_BEZ"].ToString();
string[] lines = CreateNewOrgBez(bezeichnung);
string sqlcmd = "UPDATE dbo.mydata SET WEB_OBEZ1 = '" + lines[0] + "', WEB_OBEZ2 = '" + lines[1] + "', WEB_OBEZ3 = '" + lines[2] + "' WHERE O_KURZ = '" + okuerzel + "'";
SqlConnection sqlconn2 = new SqlConnection(this.connectionString);
sqlconn2.Open();
SqlCommand cmd2 = new SqlCommand(sqlcmd, sqlconn2);
cmd2.CommandTimeout = 0;
cmd2.ExecuteNonQuery();
sqlconn2.Close();
}
reader.Close();
sqlconn.Close();
return "OK";
}
catch (Exception ex)
{
return ex.Message;
}
}
You are leaking every SqlCommand here - I suggest you review your use of SqlClient classes to find the ones that are IDisposable and restructure your code to ensure they are always freed, using the using construct.
For example, this ensures Dispose gets called even if there is an exception in the bracketed code:
using (SqlCommand cmd2 = new SqlCommand(sqlcmd, sqlconn2))
{
cmd2.CommandTimeout = 0;
cmd2.ExecuteNonQuery();
}
Using a new SqlConnection for every UPDATE is expensive too, this should be done outside the loop. Redundant connection establishment is likely the explanation for your timeout.
Take note of #ck's comment that for efficiency this type of piecemeal client-side operation is not as good as doing the heavy lifting server-side. You should be able to get this code working better, but that does not mean it's the ideal/fastest solution.
I found the issue.
You need first to get all the data records, for example in a new DataTable. The structure I used does not work, because it reads data from the database and also updates the database. After changing it to a new structure it works.
You were using two different connections to read and to update, and one of them was blocking another. This is why when you read all your data first, it began to work.
I doubt if your running into OutOfMemoryException. Can you profile your application and check the memory usage?
Since you are just overwriting the variables in While loop, why don't you try taking them out of the loop.

Categories