CascadingDropDown taking two parameters - asp.net

I have a page with 3 dropdownlist, 2nd and 3rd dropdownlist are added with CascadingDropDown. 3rd dropdownlist will take parameters from 1st and 2nd dropdownlist. So, in current example for CascadingDropDown i have found from google, they are only passing one parameter to the WebService method. How can pass two parameters to the service method, so that my 3rd dropdownlist will based on the SelectedValue of 1st and 2nd dropdownlist?
<WebMethod()> _
Public Function GetTeams(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim strConnection As String = ConfigurationManager.ConnectionStrings("nerdlinessConnection").ConnectionString
Dim sqlConn As SqlConnection = New SqlConnection(strConnection)
Dim strTeamQuery As String = "SELECT * FROM TEAM WHERE conf_id = #confid"
Dim cmdFetchTeam As SqlCommand = New SqlCommand(strTeamQuery, sqlConn)
Dim dtrTeam As SqlDataReader
Dim kvTeam As StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
Dim intConfId As Integer
If Not kvTeam.ContainsKey("Conference") Or Not Int32.TryParse(kvTeam("Conference"), intConfId) Then
Return Nothing
End If
cmdFetchTeam.Parameters.AddWithValue("#confid", intConfId)
Dim myTeams As New List(Of CascadingDropDownNameValue)
sqlConn.Open()
dtrTeam = cmdFetchTeam.ExecuteReader
While dtrTeam.Read()
Dim strTeamName As String = dtrTeam("team_name").ToString
Dim strTeamId As String = dtrTeam("team_id").ToString
myTeams.Add(New CascadingDropDownNameValue(strTeamName, strTeamId))
End While
Return myTeams.ToArray
End Function
This is the sample code i found! As you can see in the code, '#confid' will be passed from 2nd dropdownlist! So, hw do i modify this code to get the selected value from 1st dropdownlist as well??

Which web service are you referring to? Is it something you have written or someone else's webservice?
In case it is your webservice, update the method definition in it and pass two parameters. In case it is somone else's, contact the concerned person to know what best can be done.

It appears the poster is not asking about Web Services really, but about SqlCommand and adding parameters.
First, you should never EVER run sql straight from your web application like that. Put it in a stored procedure.
Second, you should run checks on the values coming in, because this is a good way for your web site users to use SQL injection attacks.
Now... Here is what you were looking for:
Dim strTeamQuery As String = "SELECT * FROM TEAM WHERE conf_id = #confid"
becomes
Dim strTeamQuery As String = "SELECT * FROM TEAM WHERE conf_id = #confid AND second_id = #secondId"
Then just add another one of these:
cmdFetchTeam.Parameters.AddWithValue("#confid", intConfId)
(with the other value, of course, like this)
cmdFetchTeam.Parameters.AddWithValue("#confid", intConfId)
cmdFetchTeam.Parameters.AddWithValue("#secondId", intSecondId)

Related

Evaluating whether a page is the result of a referral from a particular page

I have an Edit Profile page which allows users to change their information - currently it only allows users who have a record in the table 'userprofiles' to edit their information. I want newly registered users to be able to edit their profiles as well.
At the minute, I am using the ASP.NET membership system with the appropriate asp.net_ tables in an Access database to store user credentials. The 'userprofiles' table is a separate table which has more personal information in it. There is no link between the two tables
Here is my code behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsCrossPagePostBack Then
SeparateNewUserFunction()
Return
End If
If Not IsPostBack Then
DisplayData()
SaveConfirmation.Visible = False
End If
End Sub
And here is my DisplayData() function just if anyone was interested as to what it does:
Protected Sub DisplayData()
Dim conn As OleDbConnection = New OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim sql = "SELECT * FROM userprofiles WHERE TravellerName=#f1"
Dim cmd = New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#f1", User.Identity.Name)
conn.Open()
Dim profileDr = cmd.ExecuteReader()
profileDr.Read()
Dim newEmailAddress = ""
Dim newDescription = ""
If Not IsDBNull(profileDr("EmailAddress")) Then newEmailAddress = profileDr.Item("EmailAddress")
If Not IsDBNull(profileDr("Description")) Then newDescription = profileDr.Item("Description")
If Not IsDBNull(profileDr("AvatarURL")) Then ProfilePic.ImageUrl = profileDr.Item("AvatarURL")
description.Text = newDescription
email.Text = newEmailAddress
conn.Close()
End Sub
Rather than checking if a record exists in the 'userprofiles' table that matches the User.Identity.Name of the current user, I thought it would be easier just to evaluate whether or not the user had just been redirected from the Register.aspx page. (If this evaluation is true, then as you can see above, a separate "New User" function will be called).
That is my logic, but I have no clue if VB.NET has a "referrer" or "isReferred" expression? (at the minute as you can see I thought isCrossPagePostback might be the right thing but no luck!)
Any ideas?
You need to check whether or not a record exists and base your logic on that. That is the only right way to do it. As in:
What if you introduce a new page to handle registrations? This logic breaks.
What if you one day you retire and the next guy decides to rename the Register.aspx page? This logic breaks.
What if user hits back button and clicks the Register button again? This logic may break.
You should also consider a foreign key and unique constraint on that table, as well as using UserId instead of TravellerName. TravellerName can change, UserId will not.
... and yes you can the referring page by using HttpRequest.ServerVariables, which gets you a list of IIS Server Variables.

How can I make the logged-In name the default option in dropdownlist box?

Experts.
When a user logs into one of our web apps, there is a dropdownlist containing the names of all of our employees.
An employee could log into the system to record his or her entries into the database.
The employee could log the entries for another employee.
So far, an employee has had to select his or her name from the dropdown list and we don't want employees typing their names, just for consistency and to preserve data integrity.
Our problem currently is how to have employee's login name become the default option in the dropdown. The employee can select another name from the list if making the entries for another empployee.
Any ideas how to accomplish this task?
Thanks alot in advance.
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
Dim s As String
Dim reader As OleDbDataReader
txtFullName.Text = Session.Item("assignedTo").ToString
'Initialize Connection
s = "Select login_id, UserName from tblusers ORDER BY UserName"
Dim connStr As String = ConfigurationManager.ConnectionStrings("allstringconstrng").ConnectionString
Dim conn As New OleDbConnection(connStr)
Dim cmd As New OleDbCommand(s, conn)
'Open the connection
conn.Open()
Try
'Execute the Login command
reader = cmd.ExecuteReader()
'Populate the list of Users
txtLoginName.DataSource = reader
txtLoginName.DataValueField = "login_id"
txtLoginName.DataTextField = "UserName"
txtLoginName.DataBind()
'Close the reader
reader.Close()
Finally
'Close Connection
conn.Close()
End Try
End If
End Sub
<--new code -->
Try
'Execute the Login command
reader = cmd.ExecuteReader()
'Populate the list of Users
Dim currentUserName As String = ""
While reader.Read()
If (reader("login_id").ToString().Equals(currentUserName)) Then
currentUserName = reader("UserName").ToString()
End If
End While
txtLoginName.SelectedValue = currentUserName
'Close the reader
reader.Close()
Finally
'Close Connection
conn.Close()
End Try
you can use Page.User property to get the Name and then assign it to the dropdown's selected Value on Page_Load event.
Could you just simply select it by text after you populate the list? I assume you'll know the login_id once the user logs in, so you could find the username from the results of the query, like so:
UNTESTED:
string currentUserName = "";
While reader.Read()
If (reader("login_id").ToString().Equals(currentUserLogin)) Then
currentUserName = reader("UserName").ToString()
End If
End While
And then, once the list is populated via the results, select the correct user by username.
txtLoginName.Items.FindByValue(UserName).Selected = true;
Or even better yet, since you should already know the login_id, you can simply select by value from the populated drop down list, like so:
txtLoginName.SelectedValue = login_id
It's worth noting that this is making a very big assumption that the login_id will exist in the list. You may want to perform the appropriate check first to see if the login_id exists before selecting.
If you are using forms or windows authentication, wouldn't you just use:
txtLoginName.Text = User.Identity.Name
I believe this will select it if the text is in the list and matches exactly. Or, just use Sam's method. But was it the User.Identity.Name that you were looking for?

VB.net Null reference on database connection

I know I'm being an idiot here and I just can't work it out. But i'm trying to take some data back from a vb.net database. It's falling over with a Object reference not set to an instance of an object error. And before the code runs it's saying the variable is being used before it's set, but I can't see how. Code:
Private taNotifications As dsDataTableAdapters.NotificationsTableAdapter = New dsDataTableAdapters.NotificationsTableAdapter
Dim notification As dsData.NotificationsDataTable = taNotifications.GetDataByClientID(userrow.UserID)
If notification.Rows.Count > 0 Then
Dim notificationrow As dsData.NotificationsRow
Dim forwardURL As String = notificationrow.ForwardLocation
End If
It falls over on the Dim forwardURL As String = notificationrow.ForwardLocation
The problem is that you have never instantiated the notificationRow inside the if statement. You've declared it, but it doesn't belong to anything. You need to make an assignment or loop through your rows before doing anything with this object:
Dim notificationrow As dsData.NotificationsRow ' this is not instantiated
Dim forwardURL As String = notificationrow.ForwardLocation
What you really want in this case is:
For Each notificationRow As dsData.NotificationRow In notification
Dim forwardURL As String = notificationRow.ForwardLocation
' Do Something
Next
If you only HAVE one row and you know you only have 1 or 0 rows then you could use your if statement by doing:
If notification.Rows.Count > 0 Then
Dim notificationrow As dsData.NotificationsRow = _
CType(notification.Rows(0), dsData.NotificationsRow)
Dim forwardURL As String = notificationrow.ForwardLocation
End If
Edit: In the code above, I originally just had notification.Rows(0). This will produce a DataRow object, but it will not be strongly typed. You need to perform the CType that I added in order to use the custom property ForwardLocation.
You never set notificationrow to anything. Did you mean to set it like this?
Dim notificationrow As dsData.NotificationsRow = CType(notification.Rows(0), dsData.NotificationsRow)

Reducing SQL connections to just 1 - ASP.net VB

I am currently working on an asp.net web page with a GridView displaying a table from a database. This GridView has 4 DropDownLists that will be used to filter the data shown on the GridView. When the page loads 4 Sub routines are run, each one connecting to the database with a select statement to fill the DropDownList with relevant filter headings.
Initially, I had one connection with a loop that populated all of the drop downs but these contained duplicates. I then split the filling of each DDL so that the select statements could contain DISTINCT.
I would like (and am sure there is a way here) to be able to populate all of the DDLs with data from one connection.
Code for one connection:
Protected Sub FillDepDDL()
Dim conn As New SqlConnection()
conn.ConnectionString = WebConfigurationManager.ConnectionStrings("TestDBConnectionString").ConnectionString
Dim connection As New SqlConnection(conn.ConnectionString)
connection.Open()
Const FillAllQS As String = "SELECT DISTINCT [Department] FROM [Employees]"
Dim command As New SqlCommand(FillAllQS, connection)
Dim reader As SqlDataReader = command.ExecuteReader()
Dim sel As New ListItem
sel.Text = "Please Select"
sel.Value = "*"
DDLDepartment.Items.Add(sel)
While reader.Read
Dim Deplist As New ListItem()
Deplist.Value = reader("Department")
Deplist.Text = reader("Department")
DDLDepartment.Items.Add(Deplist)
End While
reader.Close()
conn.Close()
End Sub
The other 3 column names: FirstName > DDLFN, LastName > DDLLN, Wage > DDLWag.
This is only a test DB and the princibles learned here will be applied to a larger live project.
I'm sure some guru will be able to work this out easily but I just can't get my head round it even after hours of searching.
Thanks in advance.
I'm adding this in as answer because I cannot format it in a comment, but this doesn't answer the original question of how to write the sql to return all three distinct result sets. Instead, it answers how to rewrite the code you have above so that connections are properly disposed of in case of an exception.
Protected Sub FillDepDDL()
Dim Deplist As ListItem
Dim sel As New ListItem
sel.Text = "Please Select"
sel.Value = "*"
DDLDepartment.Items.Add(sel)
Using conn As New SqlConnection(WebConfigurationManager.ConnecitonString("TestDBConnectionString").ConnectionString)
Using cmd As New SqlCommand("SELECT DISTINCT [Department] FROM [Employees]", conn)
conn.Open()
Using reader = cmd.ExecuteReader()
While reader.Read
Deplist = New ListItem()
Deplist.Value = reader("Department")
Deplist.Text = reader("Department")
DDLDepartment.Items.Add(Deplist)
End While
End Using
End Using
End Using
End Sub
I don't see any reason for you to try to return all three results in a single query. That will just make your code unnecessarily complicated just to save a millisecond or two. Connection pooling handles the creation of connections on the database server for you, so opening a new connection in your code is very fast.

Calling a Class in ASP.NET

I know my ASP.NET but i have to admit, i am dumb with classes and not sure how they work exactly. Also have not worked with them yet but i want to. But what I do know is that it's a place where i can keep code for re-use correct? How will my class look with my code?
So this is my code i use on about 3 forms - but i want to save it in 1 spot and just call it from like when i click on btnSubmit.
Dim strConnection As String = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
Dim con As SqlConnection = New SqlConnection(strConnection)
Dim cmd As SqlCommand = New SqlCommand
Dim objDs As DataSet = New DataSet
Dim dAdapter As SqlDataAdapter = New SqlDataAdapter
cmd.Connection = con
cmd.CommandType = CommandType.Text
cmd.CommandText = "SELECT distinct FIELD FROM TABLE order by FIELD"
dAdapter.SelectCommand = cmd
con.Open()
dAdapter.Fill(objDs)
con.Close()
If (objDs.Tables(0).Rows.Count > 0) Then
lstDropdown.DataSource = objDs.Tables(0)
lstDropdown.DataTextField = "FIELD"
lstDropdown.DataValueField = "FIELD"
lstDropdown.DataBind()
lstDropdown.Items.Insert(0, "Please Select")
lstDropdown2.Items.Insert(0, "Please Select")
Else
lblMessage.Text = "* Our Database seem to be down!"
End If
What must i put here to execute my code above?
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
?????????????????????????????????
End Try
End Sub
Etienne
A class is (in VB.Net) is defined as so
Public Class Person
private _firstName as string
private _lastName as string
'''Constructor with no params
public Sub New()
_firstName = ""
_lastName = ""
End Sub
'Contructor with params
Public Sub New(FirstName as String, LastName as String)
_firstName = FirstName
_lastName = LastName
End Sub
Public Property FirstName As String
Get
return _firstName
End Get
Set(value as String)
_firstName = value
End Set
End Property
Public Property LastName As String
Get
return _lastName
End Get
Set(value as String)
_lastName = value
End Set
End Property
Public Function HitHomeRun() As Boolean
....'Do some stuff here
End Function
End Class
You can then instantiate the class and call its members.
Dim p as New Person()
p.FirstName = "Mike"
p.LastName = "Schmidt"
dim IsHomeRunHit As Boolean = p.HitHomeRun()
Learn more about creating and consuming classes in VB.Net.
This is a very big topic and can be defined in many different ways. But typically what you are venturing into is an N-Tier architecture.
Data Access Layer
Business Logic
UI Logic
Now the way a class can be built in your question can be done, but in the long run is prone to maintenance horror and modifiiability is cut short. Not to mention very much prone to bugs. Putting any type of data access code in your UI layer is bad practice.
This is where the power of having separate layers of classes (separation of concerns) in each layer gives you the ability to reuse code and ability to easily modify for future expansions/features etc. This is getting into Software Architecture is a very broad topic to put into one post.
But if you are really interested here are some links to point you into the right directions.
N-Tier Architecture from Wikipedia
Data Access Layer
Business Logic Layer
Martin Fowler is an expert in Architecture
There is software that eases the pain of the DAL.
1. Linq-To-SQL ability to query your data via .Net Objects (compiled queries)
2. Entity Framework Version 2 of Linq-To-SQL
And this effectively could replace all of your SQL code.
If you want to reuse the code, you should put it in a separate project. That way you can add that project to different solutions (or just reference the compiled dll).
In your web project you add a reference to the project (or to the dll if you have compiled it before and don't want to add the project to the solution).
In your new project you add a class file, for example named UIHelper. In the class skeleton that is created for you, you add a method. As the class is in a separate project, it doesn't know about the controls in the page, so you have to send references to those in the method call:
Public Shared Sub PopulateDropdowns(lstDropdown As DropDownList, lstDropdown2 As DropDownList)
... here goes your code
End Sub
In your page you call it with references to the dropdown lists that you have in the page:
UIHelper.PopulateDropdowns(lstDropdown, lstDropdown2)
This will get you started. There is a lot more to learn about using classes...
I sometimes create a "Common" class and put public Shared methods in it that I want to call from different places.
Something along these lines:
Public Class Common
Public Shared Sub MyMethod
'Do things.
End Sub
End Class
I'd then call it using:
Common.MyMethod
Obviously, you can a sub/function definition that takes the parameters you require.
Sorry if my VB.NET code is a bit off. I usually use C#.
I think you should look into using visual studio designer tools to do your data access and data binding. Search for typed datasets

Resources