SQL SELECT using a variable condition after WHERE - asp.net

I am using ASP.NET with the Webpages model and have created a database for users to post to, which is all great, then I created a page so users can edit their posts, however I want it so users can only edit their own posts.
To do this, I tried the following:
I made a variable
var EmailMatch = WebSecurity.CurrentUserName;
so if I put #EmailMatch anywhere in the html markup it will display the email address of the user who is currently logged in. Now in order to display only the posts that this user has made, I used this select statement:
var selectAllString = "SELECT * FROM SaleData WHERE Email = '#EmailMatch'";
In theory I am thinking this should work, because when the user makes a post it sends their email address to the database under the field 'Email' and it should display records that are equal to the user currently logged in. However this statement returns 0 results, I have tried all I can think of with no success, this is my last resort, can someone please tell me what I am missing? Thanks in advance..

The correct way to do this is through parameterized queries. Never ever concat strings that you do not have control over in to a query.
var EmailMatch = WebSecurity.CurrentUserName;
var selectAllString = "SELECT * FROM SaleData WHERE Email = #EmailMatch";
SqlCommand cmd = new SqlCommand(s);
cmd.Parameters.Add("#EmailMatch", EmailMatch);
var resultsTable = cmd.ExecuteReader();

var selectAllString = "SELECT * FROM SaleData WHERE Email = '" + EmailMatch + "'";
Note: This could possibly expose you to SQL Injection attacks.

cmd = new MySqlCommand("SELECT * FROM SaleData WHERE Email = #EmailMatch", MySqlConn.conn);
cmd.Parameters.AddWithValue("#EmailMatch", EmailMatch);
cmd.Prepare();
cmd.ExecuteReader();

Try this:
var selectAllString = "SELECT * FROM SaleData WHERE Email = '"+EmailMatch+"'";
or to avoid SQL Injecton, your SQL statement is correct but you have to add this in your code:
using (OleDbConnection CON = new OleDbConnection("your connection string")) {
OleDbCommand Com = CON.CreateCommand();
Com.CommandText = "SELECT * FROM SaleData WHERE Email = #EmailMatch";
Com.CommandType = CommandType.Text;
Com.CommandTimeout = 0;
Com.Connection.Open();
Com.Parameters.AddWithValue("EmailMatch",EmailMatch);
...
// continue your code from here...
}

Related

Query SQL Server using session variable

I'm trying to query a SQL Server database table based on a user variable (using ASP.NET and C#). I want to be able to pull just the user's unique records from the Waste Application Information table where the Farm Owner name is equal to the variable name (which is a string).
Here's part of my code:
conn.Open();
WasteAppData = "SELECT * FROM [WASTE APPLICATION INFORMATION] WHERE [FARM OWNER] = (user variable) ";
SqlCommand com = new SqlCommand(WasteAppData, conn);
GridView1.DataSource = com.ExecuteReader();
GridView1.DataBind();
If I replace the "(user variable)" with the actual value in the table column it does work correctly. Like this: 'Joe Smith' I've tried referencing the variable which is pulled from another webform with no luck... I think my syntax is incorrect? Any help would be great!
You need to do it this way:
WasteAppData = "SELECT * FROM [WASTE APPLICATION INFORMATION] WHERE [FARM OWNER] = #FarmOwn";
using (SqlCommand cmdSQL = new SqlCommand(WasteAppData , conn)
{
cmdSQL.Parameters.Add("#FarmOwn", SqlDbType.NVarChar).Value = strFarmOwnwer;
cmdSQL.Connection.Open();
GridView1.DataSource = cmdSQL.ExecuteReader;
GridView1.DataBind();
}
In this case "strFarmOwner" would be replaced with your actual variable that holds the value you want.

My SqlDatareader was not working

I have a code for fetching customer_id and I use a SqlDataReader for reading customer_id from SQL Server. I test witch using breakpoint and step by step debugging and I understand the SqlDataReader condition was not compile and compiler jump straight in to the connection.close line:
string strQuery = "select customer_id from Registration where username=#username and password=#password";
SqlConnection connection1 = DBConnection.getConnection();
connection1.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection1;
cmd.CommandText = strQuery;
cmd.Parameters.AddWithValue("username", txt1_username.Text);
cmd.Parameters.AddWithValue("password", txt2_password.Text);
string customer_id = cmd.ExecuteScalar() as string;
connection1.Close();
if (customer_id == null)
{
Messages myMsg = new Messages();
myMsg.CreateMessageAlert("The User does not Registered or your using incorect username or password");
}
else {
Session["customer_id"] = customer_id;
}
Although the issue is not very clear, you can try to revise the code taking following into account:
There is no need to open/close db connection for every sql query in a method. Open it once, execute all queries, close. That will make code clear and faster.
As you take connection from somewhere else, make sure it is closed before you open it (Example: Check if SQL Connection is Open or Closed)
You run 2 queries and in both cases you get only 1 result (select count(*), select customer_id). Why then in first case you do ExecuteScalar() and ExecuteReader() in the other?
The other thought is there is no need to have 2 SqlCommand(), etc if you need to return results of 2 queries. Read about Retrieving Multiple Result Sets using NextResult
And last but not least - it seems you need to check if user is already registered and if true, get his id. Why not do it in one shot? The second query is good for both cases - if user does not exist, query will not return any result, if he does - his id will be returned. Doing this way, you would need only one query and less coding.
UPDATE:
The updated code looks more clear and straightforward, but you didn't get the point of my last comment. If you select count(customer_id) you get a count that you don't need. Why not simply select customer_id and check if it was returned or not?
Example:
//string strQuery = "select count(customer_id) from Registration where username=#username and password=#password";
string strQuery = "select customer_id from Registration where username=#username and password=#password";
SqlConnection connection1 = DBConnection.getConnection();
connection1.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection1;
cmd.CommandText = strQuery;
cmd.Parameters.AddWithValue("username", txt1_username.Text);
cmd.Parameters.AddWithValue("password", txt2_password.Text);
//int intRowCount = (int)cmd.ExecuteScalar();
string customer_id = cmd.ExecuteScalar() as string;
//txt1_username.Text = intRowCount.ToString(); <-- What's this?
connection1.Close();
//if (intRowCount == 1)
if (customer_id == null)
{
// user does not exist, because sql returned no rows
... <-- do something here
} else {
Session["customer_id"] = customer_id;
}
UPDATE #2:
To troubleshoot
Make sure txt1_username.Text and txt2_password.Text have expected values. It could be that you reset the Text somewhere and that could be the reason why the query returned no result. Try to hardcode the value in the code, for example,
cmd2.Parameters.AddWithValue("username", "admin");
cmd2.Parameters.AddWithValue("password", "123");
Copy-paste entire sql in Sql Server Management Studio (or other tool) and run it from here to ensure what result it returned.
Make sure you execute it against correct database (maybe you have different databases with same tables where data is different).
This is because your username is no longer the username. It is actually 1 because of the line
int intRowCount = (int) cmd.ExecuteScalar();
txt1_username.Text = intRowCount.ToString(); <-- RED FLAG
So in the inside the If, you are actually running
SELECT customer_id FROM registration WHERE username=1 and password=my_password
Comment line 15 and you should do fine.
updated
string strQuery = "select count(*) from Employee where FullName=#username";
SqlConnection connection = DBConnection.getConnection();
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = strQuery;
cmd.Parameters.AddWithValue("username", txt1_username.Text);
cmd.Parameters.AddWithValue("password", txt2_password.Text);
int intRowCount = (int)cmd.ExecuteScalar();
txt1_username.Text = intRowCount.ToString();
if (intRowCount == 1)
{
string strquery = "select customer_id from Registration where username=#username and password=#password";
SqlCommand cmd2 = new SqlCommand();
cmd2.Connection = connection;
cmd2.CommandText = strquery;
cmd2.Parameters.AddWithValue("username", txt1_username.Text);
cmd2.Parameters.AddWithValue("password", txt2_password.Text);
SqlDataReader reader = cmd2.ExecuteReader();
if (reader.Read())
{
string customerID = reader[0].ToString();
}
}
connection.Close();`
This is complete solution for your issue.
Do not need to open connection everytime. just make sure, connection is being closed once it's used.

Invalid cast exception on remote server Guid to string

I have this code in my project:
string userId = Membership.GetUser(username).ProviderUserKey.ToString();
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("UPDATE aspnet_Membership SET IsLockedOut = 0, LastLockoutDate = #LastLockedOutDate WHERE UserId = #Userid", conn);
cmd.Parameters.Add("#LastLockedOutDate", SqlDbType.DateTime).Value = DateTime.Now;
cmd.Parameters.Add("#Userid", SqlDbType.VarChar, 255).Value = userId;
int rowsAffected = 0;
conn.Open();
rowsAffected = cmd.ExecuteNonQuery();
This works fantastic on my local machine. The user gets unlocked no problem. But for some reason when I deploy it to a demo site on the remote server I get this error:
InvalidCastException: Failed to convert parameter value from a Guid to a String
It's failing on the cmd.ExecuteNonQuery line. I tried changing the parameter to a uniqueidentifier and passing the actual guid but that didn't work either.
Anybody know why this would work locally but not on a remote server? Or know of a way I can modify the code to possibly work?
Rather than trying to manually unlock the user could you not use :-
var oUser = Membership.GetUser(username);
oUser.UnlockUser();
Membership.UpdateUser(oUser);
This allows the .NET process to do all the heavy lifting for you.
[Edit to answer the original question]
Guid gUserID = (Guid)Membership.GetUser(username).ProviderUserKey;
if (gUserID != Guid.Empty)
{
using (
var oConn =
new SqlConnection(connectionString)
{
oConn.Open();
using (SqlCommand oCmd = oConn.CreateCommand())
{
oCmd.CommandType = CommandType.Text;
oCmd.CommandText = "UPDATE aspnet_Membership SET IsLockedOut = 0, LastLockoutDate = #LastLockedOutDate WHERE UserId = #gUserID";
oCmd.Parameters.Add(new SqlParameter("#gUserID", gUserID));
oCmd.Parameters.Add(new SqlParameter("#LastLockedOutDate", DateTime.UtcNow));
oCmd.ExecuteNonQuery();
}
}
}
It may also be worth changing your DateTime.Now to DateTime.UtcNow so that if you ever have to move timezones or share with other machines out of your location you are all on a equivilent time.
If you get an error thrown on the ProviderUserKey then chances are either the user doesn't exist or the UserID isn't a GUID after all.
Maybe you can try something like
cmd.Parameters.Add("#Userid", SqlDbType.Guid).Value = new Guid(userId);
Sorry for the lame answering my own question but I resolved this. I stripped the custom membership provider out and just used the default membershipUser.UnlockUser(); and it works great. The custom provider wasn't actually doing anything anyway. I think it was developed for features that aren't being used anymore.

how to compare a value from database with the textbox value

I am using sql server 2005 and visual stdio 2008
i have a textbox in my page as txtEmailId
i want to compare this value in database with email_id column[it is a primary key]
to avoid inconsistence in database on a button click with out using custom validator
There are several ways.
1: Do a db query using sqlcommand like below:
SqlDataReader reader = null;
SqlConnection conn = new SqlConnection("Yourconnectionstring");
conn.Open();
SqlCommand cmd = new SqlCommand("select * from yourtable where email_id=#emailid", conn);
cmd.Parameters.AddWithValue("#emailid",txtEmail.Text);
reader = cmd.ExecuteReader();
if(reader!=null && reader.HasRows){
//email exists in db do something
}
My syntax might be off, but is this what you are looking for?
if txtEmailID.Text == email_id
performActionA;
Else
performActionB;
SOLUTION :>
ValidateQuery = "Select [Email_Id] from Sign_Up where (Email_Id = '"+txtEmailId.Text+"')";
SqlCommand Validatecmd = new SqlCommand(ValidateQuery, con);
String validate_email;
validate_email= (String)Validatecmd.ExecuteScalar();
if (validate_email != null)
{
lblValidateEmail.Text = "YOUR EMAIL ID IS REGISTERD TRY DIFFERENT EMAIL ID ";
}
else
{
// DO WHAT EVER U WANT
}</code>

MySQL / ASP.NET Stored Procedures

Hopefully this is not a ServerFault question...
I'm working forward on migrating a project from storing data in XML Serialization to a MySQL database. I'm using the example provided me from a previous question answered yesterday.
Connecting using phpMyAdmin and MySQL Workbench I've created a Stored Procedure called 'sprocOrderSelectSingleItem'. It seems to work well with MySQL for all I can tell. When I run the SHOW CREATE PROCEDURE sprocOrderSelectSingleItem it returns the following:
CREATE DEFINER=username#% PROCEDURE sprocOrderSelectSingleItem(IN orderID INTEGER)
BEGIN SELECT * FROM tblOrders WHERE ID=orderID; END
My cooperative ASP.NET code goes something like this:
public static Order GetItem(int ID)
{
Order objOrder = null;
using (OdbcConnection objConnection = new OdbcConnection(Utils.ApplicationConfiguration.ConnectionString))
{
OdbcCommand objCommand = new OdbcCommand("sprocOrderSelectSingleItem", objConnection);
objCommand.CommandType = CommandType.StoredProcedure;
objCommand.Parameters.AddWithValue("orderID", ID);
objConnection.Open();
using (OdbcDataReader objReader = objCommand.ExecuteReader())
{
if (objReader.Read())
{
objOrder = FillDataRecord(objReader);
}
objReader.Close();
}
objConnection.Close();
}
return objOrder;
}
When I view the page I get the following error message:
ERROR [42000] [MySQL][ODBC 5.1 Driver][mysqld-5.0.77]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sprocOrderSelectSingleItem' at line 1
Really not catching on to what could be missing or going wrong. Are there any additional tests I should/could be running to confirm things are working on the MySQL side? Am I missing a step to pass the Stored Procedure call correctly in ASP.NET? The code breaks at the line of:
using (OdbcDataReader objReader = objCommand.ExecuteReader())
Replacing the line of
OdbcCommand objCommand = new OdbcCommand("sprocOrderSelectSingleItem", objConnection);
with this instead
OdbcCommand objCommand = new OdbcCommand("SELECT * FROM tblOrders WHERE ID=" + ID + ";", objConnection);
and everything works as expected.
Thanks for any help you guys can provide.
Your can run an execute on sprocOrderSelectSingleItem in Mysql directly with the ID parameter.
It will show that your StoredProc run correctly.
Here is a sample code in C# that call a stored proc.
OdbcCommand salesCMD = new OdbcCommand("{ CALL SalesByCategory(?) }", nwindConn);
salesCMD.CommandType = CommandType.StoredProcedure;
OdbcParameter myParm = salesCMD.Parameters.Add("#CategoryName", OdbcType.VarChar, 15);
myParm.Value = "Beverages";
OdbcDataReader myReader = salesCMD.ExecuteReader();
Look at the "Call" in the OdbcCommand and the "?" for the parameter that is later supplied with a value.
Can you try something like below:
OdbcCommand cmd = new OdbcCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "{call LoadCustCliOrders(?,?,?,?)}";
cmd.Parameters.Add("CUST_ID",OdbcType.Int);
cmd.Parameters.Add("CLIENT_ID",OdbcType.Int);
cmd.Parameters.Add("DATE_FROM",OdbcType.Date);
cmd.Parameters.Add("DATE_TO",OdbcType.Date);
...
cmd.Parameters["CUST_ID"].Value = _CustId;
cmd.Parameters["CLIENT_ID"].Value = _ClientId;
cmd.Parameters["DATE_FROM"].Value = _DateFrom;
cmd.Parameters["DATE_TO"].Value = _DateTo;
cmd.ExecuteReader
Are you sure that you are using the same username or user with the same access privileges.
I think you need to add the word "CALL" before the stored proc.
It should be CALL sprocOrderSelectSingleItem and try.

Resources