Question about inserting Users/Members into a database table! - asp.net

My registration form has got a CreateUserWizard. I used its event that is fired after the user is created.
Then I obtain the users identity and key. In the last line, I send the unique key to a function inside a class that should insert the key into the Users table (the field is a primary key and is unique).
public partial class Registration : System.Web.UI.Page
{
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
MembershipUser CurrentUser = Membership.GetUser(User.Identity.Name);
int i =(int) CurrentUser.ProviderUserKey;
RegisterAdo.InsertUsers(i);
}
}
Below, I execute the query with the value that I passed and insert the user into a database
class RegisterAdo
{
public static void InsertUsers(int UsersIDentity)
{
string myConnectionString = WebConfigurationManager.ConnectionStrings["YourGuruDB"].ConnectionString;
SqlConnection sqlConnect = new SqlConnection(myConnectionString);
SqlCommand sqlCommand = new SqlCommand(RegisterAdo.insertCommand(UsersIDentity), sqlConnect);
try
{
sqlConnect.Open();
sqlCommand.ExecuteNonQuery();
}
catch (Exception x)
{
}
finally
{
sqlConnect.Close();
}
}
public static String insertCommand(int UsersIdentityToinsert)
{
string insertCommand="INSERT INTO Users(";
insertCommand += "UserID)";
insertCommand += "VALUES('";
insertCommand += UsersIdentityToinsert+"')";
return insertCommand;
}
My question is whether it is the best way to insert UserID into a table, and whether I do it right at all. I need the UserID to be unique, and the whole command executed with no fail...(just after the user was created and the whole UserCreateUser finished validating the user!!!

I would change two things mainly:
don't concatenate together your SQL statement - this opens doors to SQL injection attacks. Use parametrized queries instead - they are both safer, and they perform better (since only a single copy of the query's execution plan needs to be created and cached and will be reused over and over again)
put your SqlConnection and SqlCommand objects into using blocks so that they'll be automatically freed / disposed when the using blocks ends (and you can save yourself the finally block of the try...catch construct, too!).
So my code would look like this
public static void InsertUsers(int UsersIDentity)
{
string myConnectionString = WebConfigurationManager.ConnectionStrings["YourGuruDB"].ConnectionString;
string insertStmt =
"INSERT INTO dbo.Users(UserID) VALUES(#UserID)";
using(SqlConnection _con = new SqlConnection(myConnectionString))
using(SqlCommand _cmd = new SqlCommand(insertStmt, sqlConnect))
{
_cmd.Parameters.Add("#UserID", SqlDbType.Int).Value = UsersIDentity;
try
{
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
catch (Exception x)
{
// do something if error occurs
}
}

Related

Check at run time if primary key exists

I am working in asp.net. I have a textbox named formidtxt and another textbox is colortxt. Now what I want is that when a user enters an Form ID in formidtxt then at the same time it should start checking whether there already exists a form id with same ID that has been entered and if Form ID already exists in database then the color of colortxt textbox should change to red else it should be green.
I have an idea that it can be done by using events in text boxes but can't understand the working. My database is in SQL Server 2008.
Try this C# code;
private void Page_Load(object sender, EventArgs e)
{
// formidtxt is the name of the textbox
this.formidtxt.TextChanged += FormIDTextBox_TextChanged;
formidtxt.AutoPostBack = true;
}
Note that this method was written inside the Page_Load method.
TextChanged is an event and it occurs when the text is modified in a TextBox.
In this case, when the formidtxt (textbox) text changes, it will call the FormIDTextBox_TextChanged method.
private void FormIDTextBox_TextChanged(object sender, EventArgs e)
{
int x = 0;
// convert textbox text (string) to int
Int32.TryParse(formidtxt.Text, out x);
// call IsIDAvailableDAO method
// x is the converted int value
if (IsIDAvailableDAO(x))
{
colortxt.BackColor = System.Drawing.Color.Red;
}
else
{
colortxt.BackColor = System.Drawing.Color.Green;
}
}
This method will get the text from the textbox (formidtxt) and send it to the IsIDAvailableDAO method as a parameter.
Using the IsIDAvailableDAO method, we can check whether the ID is available in the database or not. If it is available, then the method will return a TRUE boolean value. If not, it will return a False boolean value.
According to that boolean value, you can change the color of the colortxt textbox as you want or do something else.
private Boolean IsIDAvailableDAO(int id)
{
Boolean output;
using (SqlConnection myConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Testing;Integrated Security=True"))
{
string query = #"SELECT CASE WHEN COUNT(ID) >= 1 THEN CAST( 1 as BIT ) ELSE CAST( 0 as BIT )
END As IsAvailable
FROM TableName
WHERE ID = #ID";
SqlCommand cmd = new SqlCommand(query, myConnection);
cmd.Parameters.AddWithValue("#ID", id);
myConnection.Open();
output = (Boolean)cmd.ExecuteScalar();
myConnection.Close();
}
return output;
}
In this method (IsIDAvailableDAO), Please change the query (TableName, ID, etc.) and connectionstring as appropriate.
You also has to add this namespace: using System.Data.SqlClient;
https://www.connectionstrings.com/sql-server-2008/
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/namespaces/using-namespaces

Created class is not appearing in other class files asp.net/visual basic

Very basic explanation: I have created a "User" class in a ConnectionClass.cs file and need to use it elsewhere (see below, it's a login button).
The code I'm trying to type is: `
namespace Vehicle_Website.Pages.Account
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLogin_Click(object sender, EventArgs e)
{
User user = ConnectionClass.LoginUser(txtLogin.Text, txtPassword.Text);
if (user != null)
{
//Store login variables to session
Session["login"] = user.Name;
Session["type"] = user.Type;
Response.Redirect("~/Pages/Home.aspx");
}
else
{
lblError.Text = "Login Failed";
}
}
}
}`
The "User" should be highlighting in "blue" if you like, recognizing that it's an already created class elsewhere, except is isn't and I' getting an error
"type or namespace "User" could not be found"
The exact same applies to the "ConnectionClass" line.. It should be highlighting but again says not recognized.
I have created a public class User and a public static User LoginUser(string login, string password) elsewhere and they work fine without errors. I cant understand why, in plain English, the words "User" and "ConnectionClass" are not "highlighting/changing colour" and being recognised.
I have tried changing properties to compile but seems to have done nothing.
Whatever other information you need I'll be happy to share.
UPDATE***
This is my ConnectionClass.cs file (which is working fine):
namespace Vehicle_Website.App_Code
{
public static class ConnectionClass
{
private static SqlConnection conn;
private static SqlCommand command;
static ConnectionClass()
{
string connectionString = ConfigurationManager.ConnectionStrings["DataConnection"].ToString();
conn = new SqlConnection(connectionString);
command = new SqlCommand("", conn);
}
public static User LoginUser(string login, string password)
{
//Check if user exists
string query = string.Format("SELECT COUNT (*) FROM WebsiteDB.dbo.users WHERE name = '{0}'", login);
command.CommandText = query;
try
{
conn.Open();
int amountOfUsers = (int)command.ExecuteScalar();
if(amountOfUsers == 1)
{
//User exists, check if passwords match
query = string.Format("SELECT password FROM users WHERE name = '{0}'", login);
command.CommandText = query;
string dbPassword = command.ExecuteScalar().ToString();
if(dbPassword == password)
{
//Passwords match, retrieve further information.
query = string.Format("SELECT email, user_type FROM users WHERE name = '{0}'", login);
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
User user = null;
while (reader.Read())
{
string email = reader.GetString(0);
string type = reader.GetString(1);
user = new User(login, password, email, type);
}
return user;
}
else
{
//Passwords do not match.
return null;
}
}
else
{
//User exists
return null;
}
}
finally
{
conn.Close();
}
}
}
}
UPDATE
So i think i may have found the problem but no idea how to fix:
Basically my login.aspx.cs page isnt being "linked" to my ConnectionClass.cs
By this, i mean, I have created the below line on the login.aspx.cs page :
Session["login"] = user.Name;
When i try and use ".Name" on my ConnectionClass.cs file, it isnt recognised :
user.Name);
Any idea on how to ensure both pages are communicating? I have tried correcting the namespace so they both match with no luck...
Do you have your ConnectionClass in the same project as the login button? If not you have to add a reference to the project that contains the ConnectionClass.
Also, is your ConnectionClass static? If it is not you will not be able to use it without creating first an instance of a class like this:
ConnectionClass myClass = new ConnectionClass();
User user = myClass.LoginUser(txtLogin.Text, txtPassword.Text);
You have to use full name of the class . That is ConnectedClass.User when accessing the nested class. By default nested class is private so also make sure you are using the correct access modifier
See to that the namespace Vehicle_Website.App_Code is included
in the aspx.cs which contains the button click method
Clearly see this line
public static class ConnectionClass
As per the code it is a static class and also see this constructor!
static ConnectionClass()
{
string connectionString = ConfigurationManager.ConnectionStrings["DataConnection"].ToString();
conn = new SqlConnection(connectionString);
command = new SqlCommand("", conn);
}
When is the constructor called during instanciating an object. Is
it possible instanciate the ConnectionClass? As per OOPs
programming concepts, you cannot do it. Then how will the connection
string and command will be assigned!!
Try fixing this first.

ASP.NET Cache always returns null

I am using SQLCacheDependency in my ASP.NET application with Query Notifications.
I followed this article to set up my database with success.However whenever I am trying to store data in the cache object.It just does not hold value.It is always null .I am not getting any errors or exceptions.
Here is my code
Global.asax
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
System.Data.SqlClient.SqlDependency.
Start(ConfigurationManager.ConnectionStrings["McdConn"].ToString());
}
void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown
System.Data.SqlClient.SqlDependency.
Stop(ConfigurationManager.ConnectionStrings["McdConn"].ToString());
}
public static class CacheManagement
{
public static DataTable CreateCache(string cacheName, string tableName, string query)
{
DataTable dtResult = new DataTable();
try
{
string connectionString = ConfigurationManager.ConnectionStrings["McdConn"].ToString();
dtResult = HttpContext.Current.Cache[cacheName] as DataTable;
if (dtResult == null)
{
dtResult = new DataTable();
using (var cn = new SqlConnection(connectionString))
{
cn.Open();
var cmd = new SqlCommand(query, cn);
cmd.Notification = null;
cmd.NotificationAutoEnlist = true;
SqlCacheDependencyAdmin.EnableNotifications(connectionString);
if (!SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(connectionString).Contains(tableName))
{
SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString,tableName);
}
var dependency = new SqlCacheDependency(cmd);
//SqlDataAdapter ad = new SqlDataAdapter(cmd);
//ad.Fill(dsResult);
SqlDataReader reader = cmd.ExecuteReader();
dtResult.Load(reader);
HttpContext.Current.Cache.Insert(cacheName, dtResult, dependency);
}
}
}
catch (Exception ex)
{
Exception_Log.ExceptionMethod("Web", "CacheManagement.cs", "CacheManagement", ex);
}
return dtResult = HttpContext.Current.Cache[cacheName] as DataTable;
}
}
Code Behind
var dtCachedCategories = HttpContext.Current.Cache["tbl_CategoryMaster_Cached"] as DataTable;
if (dtCachedCategories == null)
{
dtCachedCategories = CacheManagement.CreateCache("tbl_CategoryMaster_Cached","dbo.tbl_CategoryMaster_Languages", "Select * from dbo.tbl_CategoryMaster_Languages");
}
The above always returns null.
Can anyone help me in pointing out what could be missing?
Well there's a lot you can do to debug your code and arrive at a conclusion. It seems like your cached item is getting removed too frequently.
1.) Use CacheItemPriority.NotRemovable to Cache.Insert() to make sure ASP.NET doesn't removes
your item whenever it feels so. use the Insert() method explained here. Check this MSDN
article too.
2.) To find out the reason why your cached item is getting removed , log this removal action using
CacheItemRemovedCallback delegate option of your Cache.Insert() method. Check this Insert method
overload version and also this link.
3.) Make sure your dtresult as well as your reader is not null. Check the lines:
SqlDataReader reader = cmd.ExecuteReader(); & dtResult.Load(reader); , together with your logs.
4.) Check your application Pool recycle time. This link has everything related to App pool settings ( IIS 7 +).
5.) This link has a solution for App pool of IIS 6: http://bytes.com/topic/net/answers/717129-c-asp-net-page-cache-getting-removed-too-soon
Also, try using HttpRuntime.Cache method to see if it works.
System.Web.HttpRuntime.Cache.Insert(cacheName, dtResult, dependency);

My update query doesn't work on database

I wrote this code in my login page. My code doesn't any error but update query doesn't apply on my database.
Fist query works and I redirect to index.aspx but update query (second query) doesn't apply!!!!
protected void btnLogin_Click(object sender, EventArgs e)
{
Database db1 = new Database();
string query = "select * from Admins where UserName=#username and cast(Password as varbinary)=cast(#password as varbinary)";
SqlCommand smd = new SqlCommand(query, db1.sc);
smd.Parameters.AddWithValue("#username", txtUsername.Text);
smd.Parameters.AddWithValue("#password", General.CreatePasswordHash(txtPassword.Text));
SqlDataReader sdr = smd.ExecuteReader();
smd.Parameters.Clear();
if (sdr.Read())
{
Session.Add("username", sdr[0].ToString());
string nowEnter = sdr[5].ToString();
query = "update Admins set LastEnter=#lastEnter, NowEnter=#nowEnter where UserName=#username";
string now = General.getPersianDateNow() + " ساعت " + General.getPersianTimeNow();
smd.CommandText = query;
smd.Parameters.AddWithValue("#lastEnter", nowEnter);
smd.Parameters.AddWithValue("#nowEnter", now);
smd.Parameters.AddWithValue("#username", sdr[1].ToString());
sdr.Close();
smd.ExecuteNonQuery();
Response.Redirect("~/admin/Index.aspx", false);
}
else
{
lblError.Visible = true;
}
}
In my opinion the problem is with index of sdr. First one you invoke
Session.Add("username", sdr[0].ToString());
Two lines below you use
smd.Parameters.AddWithValue("#username", sdr[1].ToString());
Anyway the safest way is to create select statement with named colums instead of using *
Check that the value you are using for the username exists in the table.
You're also adding the same parameter twice. I don't know how the SqlCommand class will handle that and I can't test it right now, but I think it might be a good idea to clear your parameters (smd.Parameters.Clear()) between executions.

Object reference not set to an instance of an object ERROR

I have few textboxes whose values are to be inserted into SQl table on Submit button click. But it gives me "Object reference not set to an instance of an object" Exception. Below is the code I have written for this. Please do help me in this.
contact_new.aspx.cs
protected void btnSubmit_Click(object sender, EventArgs e)
{
DateTime dtime;
dtime = DateTime.Now;
string ocode = offercode.Text;
string firstname = firstnamepreapp.Text;
string lastname = lastnamepreapp.Text;
string email = emailpreapp.Text;
string phoneno = phonepreapp.Text;
string timetocall = besttimepreapp.SelectedItem.Value;
string time = dtime.ToString();
//Insert the data into autoprequal table
<--- GIVES ME AN ERROR ON THIS LINE --->
Insert.insertINTOautoprequal(ocode, time, firstname, lastname, email, phoneno, timetocall);
}
Insert.cs (App_code class)
namespace InsertDataAccess
{
public class Insert
{
public Insert()
{
//
// TODO: Add constructor logic here
//
}
public static bool insertINTOautoprequal(string code, string time, string first, string last, string email, string phoneno, string timetocall)
{
bool success = false;
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connstring"].ConnectionString);
conn.Open();
string query = "Insert INTO autoprequal(offercode, timeofday, firstname, lastname, emailID, phone, besttimetocall) Values(#offercode, #time, #first, #last, #email, #phoneno, #timetocall);";
SqlCommand cmd = new SqlCommand(query, conn);
try
{
cmd.Parameters.AddWithValue("#offercode", code);
cmd.Parameters.AddWithValue("#time", time);
cmd.Parameters.AddWithValue("#first", first);
cmd.Parameters.AddWithValue("#last", last);
cmd.Parameters.AddWithValue("#email", email);
cmd.Parameters.AddWithValue("#phoneno", phoneno);
cmd.Parameters.AddWithValue("#timetocall", timetocall);
if (cmd.ExecuteNonQuery() == 1) success = true;
else success = false;
return success;
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
}
}
Step through the code, as the error is most likely bubbling up from the SQL insert routine. I woulud guess the connection string is not being pulled from the configuration file, but without stepping through that is a wild guess. I would take time to learn how to debug in Visual Studio, as it will help you easily spot what cannot be a problem so you can focus on what is likely to be the problem.

Resources