ASP IF Logic not fully functioning - asp.net

I have a login form that checks for roles and when the credentials are met, the user is directed to a specific page. My issue is that when the username or password is incorrect, my logic fails to prompt the user via a label that I have in the design. I even tried implementing it via a Try/Catch and still the same result.
The Design:
<div><asp:Label ID="lblinfo" runat="server" Width="374px" CssClass="blktext"></asp:Label></div>
The code in behind the (button event-handler):
Try
Dim con As New SqlConnection(GetConnectionString())
con.Open()
Dim cmd As New SqlCommand("Check_Users", con)
cmd.CommandType = CommandType.StoredProcedure
Dim p1 As New SqlParameter("Login_name", username.Text)
Dim p2 As New SqlParameter("Login_Pwd", password.Text)
cmd.Parameters.Add(p1)
cmd.Parameters.Add(p2)
Dim rd As SqlDataReader = cmd.ExecuteReader()
'check the Role of the user logging in'
While (rd.Read())
Session("numrecord") = rd.GetValue(0).ToString()
rd.GetValue(11).ToString()
If rd.HasRows Then
If rd.GetValue(11).ToString() = 1 Then
rd.Read()
lblinfo.Text = "You are Authorized."
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
Response.Redirect("securepages/SecurePage.aspx")
Else
lblprompt.Text = "Invalid username or password."
End If
If rd.GetValue(11).ToString() = 2 Then
rd.Read()
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
Response.Redirect("securepages/newShipment.aspx")
Else
lblprompt.Text = "Invalid username or password."
End If
End If
End While
Catch ex As Exception
lblprompt.Text = "Invalid username or password."
End Try
Could I get some help as to what am failing to do here?

At the very least, please write a basic POCO object to encapsulate the values from the data layer.
Use your datareader to POPULATE the Poco object, and insert some basic logic on the Poco object.
Use the datareader quickly, then get rid of it.
Then you could actually reuse the object and your logic.
Something like this.
Then (in the presentation layer) ~respond to the values in the Poco with the redirects and such.
public enum RedirectTypeEnum
{
Unknown = 0,
SecurePage = 1,
NewShipment = 2,
}
public class LoginAttemptResult
{
public LoginAttemptResult()
{
this.NumRecord = 0;
this.ResultNumberAkaColumn11 = 0;
}
public int NumRecord { get; set; }
public int ResultNumberAkaColumn11 { get; set; }
public RedirectTypeEnum RedirectType
{
get
{
RedirectTypeEnum returnValue = RedirectTypeEnum.Unknown;
if (this.ResultNumberAkaColumn11 == 1)
{
returnValue = RedirectTypeEnum.SecurePage;
}
if (this.ResultNumberAkaColumn11 == 2)
{
returnValue = RedirectTypeEnum.NewShipment;
}
return returnValue;
}
}
public bool IsAuthorized
{
get
{
if (this.ResultNumberAkaColumn11 == 1)
{
return true;
}
if (this.ResultNumberAkaColumn11 == 2)
{
return false; /* ?? */
}
return false;
}
}
}
Then you'll have one place where you populate this object, and someone can see clearly what the biz logic is by looking at the POCO object.

One issue that I see is that you are response.redirect'ing in a Try...Catch block. Unless you put , False (which allows the code to finish executing instead of aborting) after the URL, you will throw a Thread is aborting error every time it attempts to redirect.
As for the message not showing, you show how lblinfo is created, but what about lblprompt? Perhaps you have its visible property set to false? If this is the case, make sure to change it to true in the code. Also, make sure you are not clearing its value on events such as page_load.
I have also cleaned up the code a little bit and implemented a datatable object instead of the reader:
Try
Dim cmd As New SqlCommand("Check_Users", New SqlConnection(GetConnectionString()))
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New SqlParameter("Login_name", username.Text))
cmd.Parameters.Add(New SqlParameter("Login_Pwd", password.Text))
Dim sqlDataAdapter As New SqlClient.SqlDataAdapter(cmd)
Dim dtResults As New DataTable
sqlDataAdapter.Fill(dtResults)
lblprompt.Text = "Invalid username or password."
'check the Role of the user logging in'
If dtResults.Rows.Count > 0 Then
With dtResults.Rows(0)
Session("numrecord") = .Item(0).ToString()
If .Item(11).ToString() = 1 Then
lblprompt.Text = ""
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
Response.Redirect("securepages/SecurePage.aspx", False)
ElseIf .Item(11).ToString() = 2 Then
lblprompt.Text = ""
FormsAuthentication.RedirectFromLoginPage(username.Text, True)
Response.Redirect("securepages/newShipment.aspx", False)
End If
End With
End If
Catch ex As Exception
lblprompt.Text = "An error has occurred." & ex.Message
End Try

Related

How build Get with two parameters in Web API

I'm very confused on how to configure a Get with more than one in SQL.
the answers in the forum are very fragmented and so far I have not been able to implement a solution to the code below. I know it should not be too complicated, but I can not.
My code is the one below.
Thank you very much.
[HttpGet]
[Route("cliente/{paramOne}/{paramTwo}")]
public HttpResponseMessage GetNomeNasc(string paramOne, string paramTwo)
{
try
{
Cliente cliente = null;
using (SqlConnection connection = new SqlConnection(this.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = "select id, nome, datanascimento, nascidoEm, email from clientes where nome =" + #paramOne + " and nascidoEm = " + #paramTwo;
command.Parameters.AddWithValue(paramOne, paramTwo);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
cliente = new Cliente()
{
Id = reader["id"] == DBNull.Value ? 0 : Convert.ToInt32(reader["id"]),
Nome = reader["nome"] == DBNull.Value ? string.Empty : reader["nome"].ToString(),
NascidoEm = reader["nascidoEm"] == DBNull.Value ? string.Empty : reader["nascidoEm"].ToString(),
DataNascimento = reader["datanascimento"] == DBNull.Value ? DateTime.MinValue : Convert.ToDateTime(reader["datanascimento"]),
Email = reader["email"] == DBNull.Value ? string.Empty : reader["email"].ToString()
};
}
}
connection.Close();
}
return Request.CreateResponse(HttpStatusCode.OK, cliente);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
}
}
Depending on the underlying Database Driver you can use either named or anonymous Parameters.
Your problem ist that you are not adding individual Parameters.AddwithValue(string name, Object object) expect a Parameter name and the value that is to be inserted. Look at the definition of this function
An even better way of doing that would be the following:
command.Parameters.Add("#paramOne", DbType, size).Value = paramOne
which you would have to adapt according to what is allowed for the individual column which the value should be added to. Look here.
For Example we want to insert into a column which expects an integer, you would have the following line
command.Parameters.Add("#paramOne", SqlDbType.Integer).Value = paramOne
Be aware that like this you have to add the Parameters individually. Depending on the Db Driver you have to do that in the order they are referenced in (Anonymous) or can be referenced by name and the order is of no concern.
You can also use the Parameters.AddRange() Function to either add an Array of values or pre-constructed SqlParameters.

change password in asp.net,c#,ms-access database

i am desiging a change password screen in asp.net,c#,MS-access database
i m having 4 fields
userid,
oldpassword,
newpassword
confirm password
NOW I M NOT GETTING RESULT THE COUNT RETURNS 0 I HAVE UPDATED MY CODE
my code is as follows
try
{
OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["vhgroupconnection"]
.ConnectionString);
myCon.Open();
string userid = txtuserid.Text;
string oldpass = txtoldpass.Text;
string newPass = txtnewpass.Text;
string conPass = txtconfirmpass.Text;
string q = "select user_id,passwd from register where user_id = #userid and passwd = #oldpass";
OleDbCommand cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
cmd.Parameters.AddWithValue("#oldpass", txtoldpass.Text);
OleDbDataReader re = cmd.ExecuteReader();
re.Read();
if (re["user_id"].ToString() != String.Empty && re["passwd"].ToString() != String.Empty)
{
if (newPass.Trim() != conPass.Trim())
{
lblmsg.Text = "New Password and old password does not match";
}
else
{
q = "UPDATE register SET passwd = #newPass WHERE user_id =#userid";
cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
cmd.Parameters.AddWithValue("#newPasss", txtnewpass.Text);
int count = cmd.ExecuteNonQuery();
if (count > 0)
{
lblmsg.Text = "Password changed successfully";
}
else
{
lblmsg.Text = "password not changed";
}
}
}
}
catch(Exception ex)
{
throw ex;
}
plz help me to solve the error
You're getting the error, No constructor is defined, because you can't directly instantiate this object. As stated on MSDN:
To create an OleDbDataReader, you must call the ExecuteReader method
of the OleDbCommand object, instead of directly using a constructor.
Essentially, you'd do something like the following after creating your connection and specifying your query:
OleDbDataReader re = cmd.ExecuteReader();

Secure website from SQL Injection ' using ASP.net and an Access database

I currently have a website with a normal registration and login, coded with ASP.net.
I am using an Access database, while using a C# class my friend wrote for handling most of the database actions (executeQuery, executeRead, isExits...).
Now that I've almost finished building my website, I want to start adding security - mostly to my database. I have searched for a while now for a tutorial on the subject, but I could not find anything good exept an old microsoft msdn article which I couldn't realy get its code to work.
The furthest I've got now is just no allowing any dangerous characters in the username and password, (such as ',--,;), but it kind of feels as if it is the worse solution that i can use (why shouldn't my users use this characters?).
I think that the best solution I've found is somehow insertion the variables into the query string after declaring it (something to do with "WHERE username=#user" or something like that), but i couldn't get it to work with Access and with my oleDBManager.
here is my current registration code. handle() is removing all ' from the string, and Validate() checks for dangerous parts in the string.
string username = user.Text;
string password = pass.Text;
bool isThingy = false;
if (handle(ref password)) isThingy = true;
if (handle(ref username)) isThingy = true;
if (username != "" && username != null)
{
if (password != "" && password != null)
{
if (Validate(username, password))
{
if ((db.IsExist("SELECT * FROM Table1 WHERE username='" + username + "'") == false))
{
int a = db.ExecuteQuery("INSERT INTO `Table1`(`username`, `password`, `logins`, `email`, `fname`, `lname`, `country`, `city`, `birthday`, `userid`) VALUES ('" + username + "', '" + password + "', '0', '', '', '', '', '', '', '" + Convert.ToString(Convert.ToInt32(db.ExecuteCellRead("SELECT MAX(userid) FROM Table1")) + 1) + "');");
if (!isThingy) errorLabel.Text = "Your user has been successfully registered";
else errorLabel.Text = "The ' token is invalid. your user was registered absence the '.";
}
else
errorLabel.Text = "This username is already taken";
}
else errorLabel.Text = "Invalid name format";
}
else errorLabel.Text = "Please enter a password";
}
else errorLabel.Text = "Please enter a user name";
as for the oleDBManager (named db in my code):
private OleDbConnection link; // The link instance
private OleDbCommand command; // The command object
private OleDbDataReader dataReader; // The data reader object
private OleDbDataAdapter dataAdapter; // the data adapter object
private DataTable dataTable; // the data table object
private string dbName; // the Database filename
private int version; // the usersTableG office version
private string connectionString; // the connection string for the database connection
private string provider; // the matching driver string for the connection string
private string path; // the path to the database file
...
public int ExecuteQuery(string query)
{
this.link.Open();
int rowsAffected;
// ---
this.command = new OleDbCommand(query, this.link);
try
{
rowsAffected = this.command.ExecuteNonQuery();
}
catch (InvalidOperationException e)
{
if (e.Data == null)
throw;
else
rowsAffected = -1;
}
finally
{
this.command.Dispose();
this.link.Close();
}
// ---
return rowsAffected;
}
public bool IsExist(string query)
{
this.link.Open();
// ---
this.command = new OleDbCommand(query, this.link);
this.dataReader = this.command.ExecuteReader();
bool a = this.dataReader.Read();
// ---
this.command.Dispose();
this.link.Close();
// ---
return a;
}
public string ExecuteCellRead(string query)
{
string output = "";
this.dataTable = this.ExcecuteRead(query);
foreach (DataRow row in this.dataTable.Rows)
{
foreach (object obj in row.ItemArray)
{
output += obj.ToString();
}
}
return output;
}
So, as you might see, the main problem is that the user now can not use characters as '.
It suppose the best solution would be using the # variables in the SQL queries, but I have no idea how.
[thanks for your help]
PS. i HAVE changed my tables' name ;)
edit: most of you are telling me to use these parameterized queries, but it would be great if you could give me an example of how to use them, since i've never done that
So, thanks to #Remou, my FINAL code is:
db.DoWeirdStackOverFlowStuff(
"INSERT INTO `Table1`(`username`, `password`, `logins`) VALUES (#username, #password, '0');"
, new string[] { "#username", "#password" }
, new string[] { username, password });
and
public int DoWeirdStackOverFlowStuff(string query, string[] vars, string[] reps)
{
this.link.Open();
int rowsAffected;
// ---
this.command = new OleDbCommand();
this.command.CommandText = query;
this.command.CommandType = System.Data.CommandType.Text;
this.command.Connection = this.link;
//Parameters in the order in which they appear in the query
for (int i = 0; i < vars.Length; i++)
this.command.Parameters.AddWithValue(vars[i], reps[i]);
try
{
rowsAffected = this.command.ExecuteNonQuery();
}
catch (InvalidOperationException e)
{
if (e.Data == null)
throw;
else
rowsAffected = -1;
}
finally
{
this.command.Dispose();
this.link.Close();
}
// ---
return rowsAffected;
}
for whoever needs this =]
Some notes
In MS Access, I have a saved query called UpdateUser, it looks like this:
UPDATE INTERNETSETTINGS
SET url = [#url],
databasename = [#databasename],
port = [#port],
username = [#username],
[password] = [#password]
I can refer to this query by name in my code, using a command object:
OleDbCommand Command = new OleDbCommand();
Command.CommandText = "UpdateUser"; //saved query
Command.CommandType = System.Data.CommandType.StoredProcedure;
Command.Connection = cn; //a connection to the database
//Parameters in the order in which they appear in the query
Command.Parameters.AddWithValue("#url", "a"); //a,b,c etc for my test run
Command.Parameters.AddWithValue("#databasename", "b");
Command.Parameters.AddWithValue("#port","c");
Command.Parameters.AddWithValue("#username", "d");
Command.Parameters.AddWithValue("#password", "e");
Command.ExecuteNonQuery();
I don't remember whether Access does the same thing as SQL Server here, but in SQL Server you can escape the single quote mark by doubling it:
username = username.Replace("'", "''");
So you can include single-quote marks in the string, you can store them in the database, and they can't be used as malicious string terminators.

The parameterized query which was not supplied

I keep getting this error :
The parameterized query '(#AdminEmail nvarchar(4000),#AdminPassword
nvarchar(4000))SELECT' expects the parameter '#AdminEmail', which was
not supplied.
Code:
Public Function AuthenticateAdmin() As Boolean
Dim Success As Boolean
Dim strConn As String
strConn = ConfigurationManager.ConnectionStrings("HMVDb").ToString
Dim conn As New SqlConnection(strConn.ToString())
Dim cmd As New SqlCommand("SELECT * FROM Admin WHERE AdminEmail=#AdminEmail AND Adminpassword=#Adminpassword", conn)
cmd.Parameters.AddWithValue("#AdminEmail", EMail)
cmd.Parameters.AddWithValue("#AdminPassword", Password)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet
conn.Open()
da.Fill(ds, "Admin")
conn.Close()
If ds.Tables("Admin").Rows.Count > 0 Then
Dim aemail As String = ds.Tables("Admin").Rows(0).Item("AdminEmail")
Dim apass As String = ds.Tables("Admin").Rows(0).Item("AdminPassword")
Dim aid As Integer = ds.Tables("Admin").Rows(0).Item("AdminID")
Dim aname As String = ds.Tables("Admin").Rows(0).Item("AdminName")
If EMail = aemail And Password = apass Then
ID = aid ' Shopper ID that identify Ecader
Name = aname
Success = True 'Shopper is authenticated
Else
Success = False 'Authentication fail
End If
End If
'Return the authentication result to calling program
Return Success
End Function
Your #AdminEmail variable EMail is null. You cannot pass a null on a required parameter. Use DBNull.Value.
When using null, you are informing Sql Server that you are omitting the parameter. This can be useful for an optional parameter with a default value, but causes an error for a required parameter.
I recommend that you use always use a utility function when passing a value to a command parameter.
For example:
public static object GetDataValue(object value)
{
if(value == null)
{
return DBNull.Value;
}
return value;
}
and then use
cmd.Parameters.AddWithValue("#AdminEmail", GetDataValue(EMail))
Is it possible that the EMail property is null (Email is Nothing)? I think you might get that error in that case. Be sure that EMail = String.Empty or EMail = "" before you set your parameter value.
Edit: Or as another answer suggests, you can send DBNull.Value instead if you actually want nulls in your database.
Step through your code and see what the value of Email and Password are. Chances are they are null.

Google calendar in vb.net

I am trying to convert the calendar code of C#.NET provided on google site to VB.NET and facing some conversion issues. Please help me.
Code in C#.net:
static void RetrieveAcls(CalendarService service)
{
FeedQuery query = new FeedQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/testingforfinals#gmail.com");
AtomFeed calFeed = service.Query(query);
Console.WriteLine();
Console.WriteLine("Sharing permissions for your calendars:");
// Retrieve the meta-feed of all calendars.
foreach (AtomEntry calendarEntry in calFeed.Entries)
{
Console.WriteLine("Calendar: {0}", calendarEntry.Title.Text);
AtomLink link = calendarEntry.Links.FindService(
AclNameTable.LINK_REL_ACCESS_CONTROL_LIST, null);
// For each calendar, retrieve its ACL feed.
if (link != null)
{
AclFeed feed = service.Query(new AclQuery(link.HRef.ToString()));
foreach (AclEntry aclEntry in feed.Entries)
{
Console.WriteLine("\tScope: Type={0} ({1})", aclEntry.Scope.Type,
aclEntry.Scope.Value);
Console.WriteLine("\tRole: {0}", aclEntry.Role.Value);
}
}
}
}
My code in VB.NET:
Public Sub RetrieveAcls(ByVal service As CalendarService)
Dim query As New FeedQuery
query.Uri = New Uri("http://www.google.com/calendar/feeds/testingforfinals#gmail.com")
Dim calFeed As New AtomFeed(service.Query(query))
Console.WriteLine()
Console.WriteLine("Sharing permissions for your calendars:")
Dim calendarEntry As New AtomEntry
Dim link As New AtomLink
Dim aclEntry As New AclEntry
For Each calendarEntry In calFeed.Entries
Console.WriteLine("Calendar: {0}", calendarEntry.Title.Text)
link = calendarEntry.Links.FindService(AclNameTable.LINK_REL_ACCESS_CONTROL_LIST, "")
If (link Is Nothing) Then
Dim feed As AclFeed()
feed = New AclFeed(query, service)
feed = service.Query(New AclQuery(link.HRef.ToString()))
For Each aclEntry In feed.Entries
Console.WriteLine("\tScope: Type={0} ({1})", aclEntry.Scope.Type, aclEntry.Scope.Value)
Console.WriteLine("\tRole: {0}", aclEntry.Role.Value)
Next
End If
Next
End Sub
Am facing error at "query" in "feed = New AclFeed(query, service)" which says Value of type Google.GData.Client.FeedQuery cannot be converted to 'System.Uri'... This issue is resolved... One more last issue is as per below...
Dim myQuery As New EventQuery(feedURI)
Dim myResultsFeed As New EventFeed(service.Query(myQuery))
I am getting error on "myResultsFeed" as "Argument not specified for parameter 'iService' of 'Public Sub New(uriBase As System.Uri, iService As Google.GData.Client.IService)'." and another error on "service.Query(myQuery)) as "Value of type 'Google.GData.Calendar.EventFeed' cannot be converted to 'System.Uri'."
static void DateRangeQuery(CalendarService service, DateTime startTime, DateTime endTime)
{
EventQuery myQuery = new EventQuery(feedUri);
myQuery.StartTime = startTime;
myQuery.EndTime = endTime;
EventFeed myResultsFeed = service.Query(myQuery) as EventFeed;
Console.WriteLine("Matching events from {0} to {1}:",
startTime.ToShortDateString(),
endTime.ToShortDateString());
Console.WriteLine();
for (int i = 0; i < myResultsFeed.Entries.Count; i++)
{
Console.WriteLine(myResultsFeed.Entries[i].Title.Text);
}
Console.WriteLine();
}
Well you've converted this:
AclFeed feed = service.Query(new AclQuery(link.HRef.ToString()));
to this:
Dim feed As AclFeed()
feed = New AclFeed(query, service)
feed = service.Query(New AclQuery(link.HRef.ToString()))
They're not the same at all! Your second line is calling a constructor for no obvious reason.
Just this would be fine:
Dim feed As AclFeed = service.Query(New AclQuery(link.HRef.ToString()))
It's also not clear why you've got lines like this:
Dim calendarEntry As New AtomEntry
Why are you calling the parameterless constructor for AtomEntry? Why are you declaring the variable outside the ForEach loop at all? Just use:
For Each calendarEntry As AtomEntry In calFeed.Entries
EDIT: For the other issue, I think you just need:
Dim myEventFeed As CType(service.Query(myQuery), EventFeed)
If you could provide the full method, that would help.
I'm not sure if it works, but this is the direct c#->VB.Net-Translation from developerfusion, the syntax seems to be correct. Only as a hint for your next problems ;)
Shared Sub RetrieveAcls(ByVal service As CalendarService)
Dim query As New FeedQuery()
query.Uri = New Uri("http://www.google.com/calendar/feeds/testingforfinals#gmail.com")
Dim calFeed As AtomFeed = service.Query(query)
Console.WriteLine()
Console.WriteLine("Sharing permissions for your calendars:")
' Retrieve the meta-feed of all calendars.
For Each calendarEntry As AtomEntry In calFeed.Entries
Console.WriteLine("Calendar: {0}", calendarEntry.Title.Text)
Dim link As AtomLink = calendarEntry.Links.FindService(AclNameTable.LINK_REL_ACCESS_CONTROL_LIST, Nothing)
' For each calendar, retrieve its ACL feed.
If Not link Is Nothing Then
Dim feed As AclFeed = service.Query(New AclQuery(link.HRef.ToString()))
For Each aclEntry As AclEntry In feed.Entries
Console.WriteLine(vbTab & "Scope: Type={0} ({1})", aclEntry.Scope.Type, aclEntry.Scope.Value)
Console.WriteLine(vbTab & "Role: {0}", aclEntry.Role.Value)
Next
End If
Next
End Sub

Resources