I have created asp.net WebService. I want to update user's info after validating him , means if new UserName entered by him is not already exist than only he can update new UserName otherwise not .
The problem is that it validates the user successfully but when i am trying to specify new UserName which is not exist than it gives me an error like ;
Request format is unrecognized for URL unexpectedly ending in '/UpdateUserInfo'.
Following is my code :
public int UpdateUserInfo(string oldusername, string newusername, string mailid, string password)
{
string validateUser = "Select UserName from tbl_UserInfo where UserName='" + newusername + "' ";
con = new MySqlConnection(conString);
con.Open();
MySqlCommand cmd1 = new MySqlCommand(validateUser, con);
string User = cmd1.ExecuteScalar().ToString();
con.Close();
if (User == newusername)
{
return 0;
}
else
{
string updateUser = "Update tbl_UserInfo SET UserName='" + newusername + "',Password='" + password + "',Email_ID='" + mailid + "' where UserName='" + oldusername + "' ";
con = new MySqlConnection(conString);
con.Open();
MySqlCommand cmd = new MySqlCommand(updateUser, con);
int success = cmd.ExecuteNonQuery();
con.Close();
if (success > 0)
{
return success;
}
else
return 0;
}
}
NOTE : I want result as ;
IF my UserName is A and when i update that UserName with same name
i.e A than it should not be updated but when i give another name as B
than it should be updated by B i.e now UserName A becomes the B
what can be problem ?
Please give solution.
Thanks..
Oh, please use parametrized queries. Ah, and dispose your IDisposable resources. You wil save yourself headaches, SQL injections, improperly formatted data, ...
public int UpdateUserInfo(
string oldusername,
string newusername,
string mailid,
string password
)
{
using (var con = new MySqlConnection(conString))
using (var cmd = con.CreateCommand())
{
con.Open();
cmd.CommandText = "SELECT count(UserName) from tbl_UserInfo where UserName = #newusername";
cmd.Parameters.AddWithValue("#newusername", newusername);
var count = (long)cmd.ExecuteScalar();
if (count < 1)
{
return 0;
}
}
using (var con = new MySqlConnection(conString))
using (var cmd = con.CreateCommand())
{
con.Open();
cmd.CommandText = "UPDATE tbl_UserInfo SET UserName = #newusername, Password = #password, Email_ID = #mailid WHERE UserName = #oldusername";
cmd.Parameters.AddWithValue("#newusername", newusername);
cmd.Parameters.AddWithValue("#password", password);
cmd.Parameters.AddWithValue("#mailid", mailid);
cmd.Parameters.AddWithValue("#oldusername", oldusername);
return cmd.ExecuteNonQuery();
}
}
or you could also split those into separate methods:
public bool UsernameExists(string username)
{
using (var con = new MySqlConnection(conString))
using (var cmd = con.CreateCommand())
{
con.Open();
cmd.CommandText = "SELECT count(UserName) from tbl_UserInfo where UserName = #newusername";
cmd.Parameters.AddWithValue("#newusername", username);
return (long)cmd.ExecuteScalar() > 0;
}
}
public int Update(string oldusername, string newusername, string mailid, string password)
{
using (var con = new MySqlConnection(conString))
using (var cmd = con.CreateCommand())
{
con.Open();
cmd.CommandText = "UPDATE tbl_UserInfo SET UserName = #newusername, Password = #password, Email_ID = #mailid WHERE UserName = #oldusername";
cmd.Parameters.AddWithValue("#newusername", newusername);
cmd.Parameters.AddWithValue("#password", password);
cmd.Parameters.AddWithValue("#mailid", mailid);
cmd.Parameters.AddWithValue("#oldusername", oldusername);
return cmd.ExecuteNonQuery();
}
}
public int UpdateUserInfo(string oldusername, string newusername, string mailid, string password)
{
if (!UsernameExists(newusername))
{
return Update(oldusername, newusername, mailid, password);
}
return 0;
}
Related
I am working on updating a huge amount of data. About 200k of data in the particular table. But I find my code inefficient and slow. Is there a way to optimize this code and make it twice or thrice faster? I am trying to convert their existing password to hashed. I tried linq before but I encounter an "Execution Timeout" issue. Until now I can't find a solution to it. The code below was the one that I am currently using.
var hashedProvider = Membership.Providers["HashedProvider"];
if (hashedProvider != null)
{
using (SqlConnection con = new SqlConnection(System.Configuration
.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString))
{
con.Open();
string sql = "SELECT Email from aspnet_membership where IsLockedOut = '0'" +
" AND IsApproved = '1' And PasswordFormat != '1'";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader Reader = cmd.ExecuteReader();
while (Reader.Read())
{
var UserName = Reader["Email"].ToString();
MembershipUser user = Membership.GetUser(UserName);
if (user != null)
{
Guid userID = new Guid(user.ProviderUserKey.ToString());
string CurrentPassword = user.GetPassword();
try
{
UpdateUser(userID, 1);
var resetPassword = hashedProvider.ResetPassword(UserName, null);
bool Password_Changed = hashedProvider.ChangePassword(
UserName, resetPassword, CurrentPassword);
if (!Password_Changed)
{
UpdateUser(userID, 2);
}
}
catch (Exception e)
{
UpdateUser(userID, 2);
}
}
}
if (Reader != null)
Reader.Close();
}
}
Below is the code for UpdateUser() method.
public static void UpdateUser(Guid userID, int type)
{
for (Int32 attempt = 1; ;)
{
using (SqlConnection con = new SqlConnection(System.Configuration
.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString))
{
con.Open();
string Sql = "UPDATE [aspnet_Membership] SET [PasswordFormat] = #Type where" +
" UserID = #UserID";
SqlCommand cmd = new SqlCommand(Sql, con);
cmd.Parameters.AddWithValue("#UserID", userID);
cmd.Parameters.AddWithValue("#Type", type);
cmd.ExecuteNonQuery();
break;
}
}
}
I want to set isLogged to 1 after login, login work but query doesn't work.
Query :
//
public static string loginUpdate = #"UPDATE users SET isLogged = #isLogged WHERE username = #username";
//
public bool userLogin(string userName, string password)
{
SqlConnection conn = db.initializare();
UserModel user = null;
int userId ;
int isLogged = 1;
try
{
cmd = new SqlCommand(Query.loginCheck, conn);
//cmd = new SqlCommand(Query.loginUpdate, conn);
cmd.Parameters.Add(new SqlParameter("username", userName));
cmd.Parameters.Add(new SqlParameter("password", password));
cmd.Parameters.AddWithValue("#isLogged", isLogged);
reader = cmd.ExecuteReader();
while (reader.Read())
{
userName = reader["username"].ToString();
password = reader["password"].ToString();
userId = Int32.Parse(reader["userID"].ToString());
user = new UserModel(userName, password,userId);
if (user != null)
{
cmd = new SqlCommand(Query.loginUpdate, conn);
return true;
}
}
}
catch (Exception ex)
{
var mesajEroare = ex.Message + "-" + ex.InnerException; ;
}
finally
{
conn.Dispose();
conn.Close();
}
return false;
}
You may need to write two separate SqlCommands to perform two operations:
For login check
For login update
Also, always make it a habit to use the using statement when dealing with an object that eats resources such as SqlConnection and SqlCommand. so objects will be automatically disposed after using them.
This will make your code cleaner without explicitly calling the Dispose() call.
Finally, I would suggest you place your SQL operation outside your Button Click event to avoid getting your code more complex. That way it's clean and easy to manage.
To summarize that, here's how your code is going to look like:
private string GetUserPassword(string userName){
using (SqlConnection connection = db.initializare()) {
string sqlQuery = "SELECT password FROM users WHERE username = #UserName";
using (SqlCommand cmd = new SqlCommand(sqlQuery, connection)) {
connection.Open();
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#UserName", userName);
var result = cmd.ExecuteScalar();
return (result == DBNull.Value) ? string.Empty : result;
}
}
}
private void UpdateLogin(string userName, int isLogged){
using (SqlConnection connection = db.initializare()) {
string sqlQuery = "UPDATE users SET isLogged = #isLogged WHERE username = #username";
using (SqlCommand cmd = new SqlCommand(sqlQuery, connection)) {
connection.Open();
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#UserName", userName);
cmd.Parameters.AddWithValue("#isLogged", isLogged);
cmd.ExecuteNonQuery();
}
}
}
public bool UserLogin(string userName, string password)
{
string userPassword = GetUserPassword(userName);
if (password.Equals(userPassword)){
UpdateLogin(userName,1);
return true;
}
else{
//username or password is incorrect
}
return false;
}
I am a newbie.
I am attempting to check for duplicate database entries. My problem is:
I would like a success alert shown if the entry is successful.
A notification of duplicates shown if a duplicate exists.
My issue is: the alert for duplicates gets shown multiple times, however, the entry is never created if no duplicates exist.
This is my code:
/// <summary>
/// The following procedure creates the user account in the database The procedure first attempts to
/// perform a check for duplicates before submitting the registration info
/// </summary>
protected void BTN_CreateACNT_Click(object sender, EventArgs e)
{
string InsertQuery = "";
string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Reimburse"].ConnectionString;
InsertQuery = "Insert into TBL_Logins (FirstName, LastName, EmailAddress, Password) VALUES(#FirstName, #LastName, #EmailAddress, #Password)";
String FirstNameSTR = FN.Text.Trim();
String LastNameSTR = LN.Text.Trim();
String EMailAddressSTR = EmailAddress.Text.Trim();
byte[] PassByte = StrToByteArray(PWD.Text.Trim());
// CheckUser(EMailAddressSTR);
while (CheckUser(EMailAddressSTR) == false)
{
SqlConnection CN = new SqlConnection(ConnectionString);
SqlCommand CMD = new SqlCommand(InsertQuery, CN);
CMD.CommandType = CommandType.Text;
CMD.Parameters.AddWithValue("#Firstname", FirstNameSTR);
CMD.Parameters.AddWithValue("#LastName", LastNameSTR);
CMD.Parameters.AddWithValue("#EmailAddress", EMailAddressSTR);
CMD.Parameters.AddWithValue("#Password", PassByte);
CN.Open();
CMD.ExecuteNonQuery();
Response.Write("<script language='javascript'>alert('Account created successfully.');</script>");
CN.Close();
}
}
public bool CheckUser(String UserString)
{
String UserSelect = "Select * from TBL_Logins where EmailAddress = #EmailAddress";
int MailCount = 0;
string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Reimburse"].ConnectionString;
SqlConnection CN = new SqlConnection(ConnectionString);
UserString = EmailAddress.Text.Trim();
SqlCommand CMD = new SqlCommand(UserSelect, CN);
CMD.Parameters.AddWithValue("#EmailAddress", UserString);
CN.Open();
SqlDataReader dr = CMD.ExecuteReader();
while (dr.Read())
{
if (UserString == dr["EmailAddress"].ToString())
{
Response.Write("<script language='javascript'>alert('This EMail address is already taken. Please try again.');</script>");
// return true;
}
}
CN.Close();
return true;
}
protected void BTN_CreateACNT_Click(object sender, EventArgs e)
{
string InsertQuery = "";
string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Reimburse"].ConnectionString;
InsertQuery = "Insert into TBL_Logins (FirstName, LastName, EmailAddress, Password) VALUES(#FirstName, #LastName, #EmailAddress, #Password)";
String FirstNameSTR = FN.Text.Trim();
String LastNameSTR = LN.Text.Trim();
String EMailAddressSTR = EmailAddress.Text.Trim();
byte[] PassByte = StrToByteArray(PWD.Text.Trim());
// CheckUser(EMailAddressSTR);
while(CheckUser(EMailAddressSTR) == false)
{
SqlConnection CN = new SqlConnection(ConnectionString);
SqlCommand CMD = new SqlCommand(InsertQuery, CN);
CMD.CommandType = CommandType.Text;
CMD.Parameters.AddWithValue("#Firstname", FirstNameSTR);
CMD.Parameters.AddWithValue("#LastName", LastNameSTR);
CMD.Parameters.AddWithValue("#EmailAddress", EMailAddressSTR);
CMD.Parameters.AddWithValue("#Password", PassByte);
CN.Open();
CMD.ExecuteNonQuery();
Response.Write("<script language='javascript'>alert('Account created successfully.');</script>");
CN.Close();
}
}
public bool CheckUser(String UserString)
{
String UserSelect = "Select * from TBL_Logins where EmailAddress = #EmailAddress";
int MailCount = 0;
string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Reimburse"].ConnectionString;
SqlConnection CN = new SqlConnection(ConnectionString);
UserString = EmailAddress.Text.Trim();
SqlCommand CMD = new SqlCommand(UserSelect,CN);
CMD.Parameters.AddWithValue("#EmailAddress", UserString);
CN.Open();
SqlDataReader dr = CMD.ExecuteReader();
while (dr.Read())
{
if (UserString == dr["EmailAddress"].ToString())
{
Response.Write("<script language='javascript'>alert('This EMail address is already taken. Please try again.');</script>");
// return true;
}
}
CN.Close();
return true;
}
Looks like the CheckUser method always returns true and that's why the insertion does not work, update the method to return false by default:
while (dr.Read())
{
if (UserString == dr["EmailAddress"].ToString())
{
Response.Write("<script language='javascript'>alert('This EMail address is already taken. Please try again.');</script>");
return true; // return true if user exists
}
}
CN.Close();
return false; // return false if the user does not exist
It is also recommended to use using block to dispose the DB connection instead of manually invoking the Close() method.
I'm trying to check if a username with the given passwort exists in my database, if it exists it should return true otherwise it should return false.
My current function looks like the following:
public bool user_check(string username, string password)
{
string query = "SELECT username, password from swear_tool where username='" + username + "' and password = '" + password + "'";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
return true;
}
}
else
{
return false;
}
dataReader.Close();
this.CloseConnection();
}
}
But I receive the following error message:
Error CS0161 'database_connector.user_check(string, string)': not all
code paths return a value
What am I doing wrong?
Just add a return false; at the end. Also you don't need the else return false in the inner if
public bool user_check(string username, string password)
{
string query = "SELECT username, password from swear_tool where username='" + username + "' and password = '" + password + "'";
if (this.OpenConnection())
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
return true;
}
}
dataReader.Close();
this.CloseConnection();
}
return false;
}
Also see that if you have records then you return true and never close your connection and object. Maybe do this instead:
public bool user_check(string username, string password)
{
string query = "SELECT username, password from swear_tool where username='" + username + "' and password = '" + password + "'";
bool hasRecords = false;
if (this.OpenConnection())
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
hasRecords = true;
break;
}
}
dataReader.Close();
this.CloseConnection();
}
return hasRecords;
}
last thing: look into Parameterized Queires to avoid SQL Injections
Just add a return false at the end of the method:
public bool user_check(string username, string password)
{
string query = "SELECT username, password from swear_tool where username='" + username + "' and password = '" + password + "'";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
return true;
}
}
else
{
return false;
}
dataReader.Close();
this.CloseConnection();
}
return false; //<<---- This is where it does not know what to do if any above conditions fail.
}
if this check returns false:
if (this.OpenConnection() == true)
You exit without returning anything.
Error CS0161 occurs when a function that specifies a return type in its signature contains a path through the function that does not return a value. In your case your function does not return a value when the this.OpenConnection() method returns false.
To prevent this error from being reported by the compiler, all paths should return a value:
public bool user_check(string username, string password)
{
string query = "SELECT username, password from swear_tool where username='" + username + "' and password = '" + password + "'";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
return true;
}
}
else
{
return false;
}
dataReader.Close();
this.CloseConnection();
}
return false;
}
I take this opportunity to let you know about SQL injection
Your code is vulnerable to SQL injection because you're concatenating user input into your query. You're encouraged to use parameterized queries, for more information about this topic check out this link
That's because you are writing your return inside if while blocks only.Besides I suggest you use parameterized query
public bool user_check(string username, string password){
string query = "SELECT username, password From swear_tool Where "+
"username=#uname and password=#password";
if (this.OpenConnection() == true){
using(MySqlCommand cmd = new MySqlCommand(query, connection)){
cmd.Parameters.AddWithValue("#uname",usename);
cmd.Parameters.AddWithValue("#password",password);
using(MySqlDataReader dataReader = cmd.ExecuteReader()){
if (dataReader.HasRows){
while(dataReader.Read()){
return true;
}
}
}
}
this.CloseConnection();
}
return false;
}
Nice and Clean and Safe and Shorter
The previous answer do not close the connection when a user exists.
Try this:
public bool user_check(string username, string password)
{
string query = "SELECT username, password from swear_tool where username='" + username + "' and password = '" + password + "'";
if (this.OpenConnection())
{
try
{
using (MySqlCommand cmd = new MySqlCommand(query, connection))
{
using (MySqlDataReader dataReader = cmd.ExecuteReader())
{
if (dataReader.HasRows)
{
while (dataReader.Read())
{
return true;
}
}
}
}
}
finally
{
this.CloseConnection();
}
}
return false;
}
Bussiness Access Layer :
public static int login(string userlogin, string pwdlogin)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = selectstr;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
id = cmd.ExecuteNonQuery();
cmd = null;
con.Close();
return id;
}
Login.cs
protected void Button1_Click(object sender, EventArgs e)
{
int id = BusinessAccessLayer.login(userlogin.Text.Trim(), pwdlogin.Text.Trim());
if (id > 0)
{
message.Text = " valid";
}
else
{
message.Text = "in valid";
}
}
Okay, there are multiple things wrong here:
1) You should use using statements to make sure you close your connection and command even if exceptions are thrown
2) You should use parameterized SQL instead of putting the values directly into your SQL statement, to avoid SQL Injection Attacks
3) You appear to be storing passwords in plain text. Don't do that. Use a salted hash or something similar (ideally something slow to compute).
4) You're ignoring .NET naming conventions; methods should be in PascalCase
5) Your SQL never looks at any field which appears to be related to the user ID. It's not clear what you expect ExecuteNonQuery to return, but if you want the actual ID, you'll need to refer to it in the SQL. (Even if initially you just want to know whether or not the user's password is valid, I strongly suspect that at some point you'll want to user the real user ID, so you should make your code return it. If you really only want to know whether or not the password is valid, you should change the method's return type to bool.)
6) You're using ExecuteNonQuery when your command clearly is a query. Either use ExecuteReader or ExecuteScalar instead. (ExecuteNonQuery is meant for insert, delete and update statements, and it returns you the number of rows affected by the command.)
So something like:
public static int Login(string user, string password)
{
using (var conn = new SqlConnection(GetConnectionString()))
{
conn.Open();
string sql = "select Id, PasswordHash from logins where Username=#Username";
using (var command = new SqlCommand(sql))
{
command.Parameters.Add("#Username", SqlDbType.NVarChar).Value = user;
using (var reader = command.ExecuteRead())
{
if (reader.Read())
{
int id = reader.GetInt32(0);
string hash = reader.GetString(1);
// TODO: Hash provided password with the same salt and compare
// results
if (CheckPassword(password, hash))
{
return id;
}
}
return 0; // Or use an int? return type and return null
}
}
}
}
The ExecuteNonQuery is used for For UPDATE, INSERT, and DELETE statements.
For SELECT statements, use ExecuteReader
public static int login(string userlogin, string pwdlogin)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = selectstr;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
id++;
}
cmd = null;
reader.Close();
con.Close();
return id;
}
You can't use .ExecuteNonQuery if you want a result. Use .ExecuteReader.
public static int login(string userlogin, string pwdlogin)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
string selectstr = "SELECT UserId FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = selectstr;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
id = reader.GetInt32("UserId");
reader.Close();
con.Close();
return id;
}