Classic ASP: querystring handler - asp-classic

I've done this a long time ago, now I can't find the function. It shouldn't be too complicated, but I wonder if there's any news on this before I go and do it again...
Take this:
www.example.com?query=whatever&page=1
Now imagine I press button to page 2, it will become:
www.example.com?query=whatever&page=2
Always keeping the rest of the querystring intact. Now picture on page 2 I press the button to order by date, it should turn into:
www.example.com?query=whatever&page=1&order=date
Problem is, on the ASP code for ordering, I don't want to handle every other querystring. So I need a function to handle it for me and be able to do something like the following examples:
date
next page
all pages
This is just an initial idea of what I am going to do if I still can't find a ready solution... Again, just wondering if there's anything new out there to handle all this in ways I haven't even imagined yet.

If it's of anyone's interest, here's the quite confusing code I rolled on yesterday:
'Build a string QueryString from the array Request
function bdl_qs (req_qs)
dim result, qa, item
result = empty
qa = "?"
if isnull(req_qs) or isempty(req_qs) then req_qs = Request.QueryString
for each item in req_qs
result = result & qa & item
result = result & "=" & req_qs(item)
qa = "&"
next
bdl_qs = result
end function
'Build a string QueryString ontop of the supplied one, adding the query and / or value(s) to it
function add_qs (qs, q, s)
dim result
result = qs
if left(result, 1) = "?" then
result = result & "&" & q
else
result = "?" & q
end if
if not isnull(s) and not isempty(s) then
result = result & "=" & s
end if
add_qs = result
end function
'Build a string QueryString ontop of the supplied one, removing the selected query and / or values
function del_qs (qs, q)
dim result, item
result = qs
if left(qs, 1) = "?" then
dim rqs, qa
rqs = result
result = "?"
rqs = right(rqs, len(rqs)-1) 'remove the "?"
rqs = Split(rqs, "&") 'separate the queries
qa = ""
for each item in rqs
dim rq
rq = Split(item, "=") 'separate the query to analyze the name only
if rq(0) <> q then 'good for rebuilding
result = result & qa & item
qa = "&"
end if
next
end if
del_qs = result
end function
'Build a string QueryString ontop of the supplied one, setting the query to the value
function set_qs (qs, q, s)
set_qs = add_qs(del_qs(qs, q), q, s)
end function

Related

How can I compare a text box entry against a list of database values in the Text_Changed event

as the title states I am trying to compare or validate a text box entry against a list of acceptable values stored in my database. As of now I have taken the values from my database and store them in a List(of String) and I have a for loop that loops through that list and returns true if the values match, if the values do not match it will return false. Below I have attached the code I am currently working with.
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
Dim listEType As List(Of String) = New List(Of String)
Dim eType As String = txtSearchOC.Text
Dim strResult As String = ""
lblPrefix.Text = ""
lblList.Text = ""
Dim TypeIDQuery As String = "
SELECT a.OrderCode
FROM SKU AS a
INNER JOIN EnrollmentType AS e ON a.EnrollmentTypeID = e.TypeID
INNER JOIN Enrollment AS f ON e.RecID = f.EnrollmentTypeID
WHERE f.AccountNumber = '12345';
"
Using connEType As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmdEType As New SqlCommand(TypeIDQuery, connEType)
cmdEType.Parameters.Add("#AccountNumber", SqlDbType.VarChar, 15).Value = "12345"
connEType.Open()
Using sdrEType As SqlDataReader = cmdEType.ExecuteReader
While sdrEType.Read
listEType.Add(sdrEType("OrderCode").ToString)
End While
End Using
End Using
End Using
For Each Item As String In listEType
strResult &= Item & ", "
Next
For i = 0 To listEType.Count - 1
If eType = listEType(i) Then
lblPrefix.Text = "True"
End If
If eType <> listEType(i) Then
lblList.Text = "Error"
End If
Next
'lblList.Text = strResult
End Sub
In the code I declare my list and a variable to store the text value of the text box. To verify that it pulled the appropriate values from the database I have the strResult variable and can confirm that the appropriate values are being stored.
The problem I am having has to do with the For loop I have at the bottom, when I enter in a valid value that is contained in the listEType, I get the confirmation message of "True" indicating it has matched with one of the values, but I also get the "Error" message indicating that it does not match. If I enter in a value that is not contained in the list I only get the "Error" message which is supposed to happen.
My question is, based on the code I have supplied, why would that For loop be returning both "True" and "Error" at the same time for a valid entry? Also, if there is a better way to accomplish what I am trying to do, I am all ears so to speak as I am relatively new to programming.
Well, as others suggested, a drop down (combo box) would be better.
However, lets assume for some reason you don't want a combo box.
I would not loop the data. You have this amazing database engine, and it can do all the work - and no need to loop the data for such a operation. Why not query the database, and check for the value?
Say like this:
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
If txtSearchOC.Text <> "" Then
Dim TypeIDQuery As String = "
SELECT a.OrderCode FROM SKU AS a
INNER JOIN EnrollmentType AS e ON a.EnrollmentTypeID = e.TypeID
INNER JOIN Enrollment AS f ON e.RecID = f.EnrollmentTypeID
WHERE f.AccountNumber = #AccoutNumber;"
Using connEType As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmdEType As New SqlCommand(TypeIDQuery, connEType)
cmdEType.Parameters.Add("#AccountNumber", SqlDbType.NVarChar).Value = txtSearchOC.Text
connEType.Open()
Dim rstData As New DataTable
rstData.Load(cmdEType.ExecuteReader)
If rstData.Rows.Count > 0 Then
' we have a valid match
lblPrefix.Text = "True"
Else
' we do not have a valid match
lblPrefix.Text = "False"
End If
End Using
End Using
End If
End Sub
So, pull the data into a data table. You can then check the row count, or even pull other values out of that one row. But, I don't see any need for some loop here.

Callback URL is ignoring parameter value after &

I got stuck at this point. After login i am getting referral-url which i am putting into www.url.com?par1=val&callback="referral-url". My referral url is like www.ref-url.com?param1=val1&param2=val2&param3=val3. My problem is that i am getting a cut url i.e., www.ref-url.com?param1=val1 after login. I think it is ignoring url after '&'.I am using classic asp for development. Any Help would be very helpful.
You need to use Server.URLEncode if you're including a URL as a querystring parameter, especially if the included URL also contains querystrings.
Dim login_redirect, login_referrer
login_redirect = "http://www.url.com/?par1=val&callback="
login_referrer = "http://www.ref-url.com/?param1=val1&param2=val2&param3=val3"
response.write login_redirect & Server.URLEncode(login_referrer)
Output:
http://www.url.com/?par1=val&callback=http%3A%2F%2Fwww%2Eref%2Durl%2Ecom%2F%3Fparam1%3Dval1%26param2%3Dval2%26param3%3Dval3
Passing the URL with query inside another URL query is a bit tricky. The only way it works is to encode it. For example:
https://website.com/?a=1&url=https%3A%2F%2Fwebsite.com%2F%3Fz%3D1%26y%3D2
But, when you want to return to the url you passed through query, you need to decode it otherwise it will not work. You can use the following function on your "login Page" before redirecting the url.
Function URLDecode(sConvert)
Dim aSplit
Dim sOutput
Dim I
If IsNull(sConvert) Then
URLDecode = ""
Exit Function
End If
' convert all pluses to spaces
sOutput = REPLACE(sConvert, "+", " ")
' next convert %hexdigits to the character
aSplit = Split(sOutput, "%")
If IsArray(aSplit) Then
sOutput = aSplit(0)
For I = 0 to UBound(aSplit) - 1
sOutput = sOutput & _
Chr("&H" & Left(aSplit(i + 1), 2)) &_
Right(aSplit(i + 1), Len(aSplit(i + 1)) - 2)
Next
End If
URLDecode = sOutput
End Function
For example, you should have above function and the following code on your login page:
Dim callback
callback = Request("callback")
callback = URLDecode(callback)
Response.redirect(callback)

Escaping apostrophe/single quote in parameterized sql in asp

I'm new to parametrized SQL. I've got a query in an .asp page that's getting one or more client names from a form. These are held in an array called clientArr and then passed through to SQL server as parameters. I'm escaping the ' as '' but this doesn't appear to be working. If I run the query with a client name like McDonald's, it returns no results.
clientArr(y) = Replace(clientArr(y),"'","''"
...
if qsClient > "" Then
dim booComma
booComma = false
if mySQLwhere > "" Then
mySQLwhere = mySQLwhere& " AND "
End if
mySQLwhere = mySQLwhere & " (p.client IN ( "
for y = 0 to Ubound(clientArr)
if booComma = true Then
mySQLwhere = mySQLwhere & ","
end if
mySQLwhere = mySQLwhere & "?"
booComma = true
Next
mySQLwhere = mySQLwhere & ")) "
end if
...
if qsClient > "" Then
for y = 0 to Ubound(clientArr)
Response.write clientArr(y)
set prm = cmd.CreateParameter("#prm", 129, 1, 50, clientArr(y))
cmd.Parameters.Append prm
next
end if
If I run the query directly or create it by concatenating strings rather then use parameters, it works fine. It also works fine is I use a client name without an apostrophe.
Any help would be much appreciated. Happy to provide more info if I can.
Thanks,
Tim
After working on this for far too long, it just hit me. Passing the parameter straight through like this means that I don't need to escape it at all. If I remove that replace statement, it works just fine keeping the single quote. I was definitely over-thinking this.

Creating multiple querystrings from drop down lists - Could be 1, 2 or 3 querystrings. How do I do it?

I have a gridview which can be filtered from one or more values in a querystring. That all works great: e.g. "?subject=Maths&authorName=Bond_James&type=Magazine"
The values passed to the query string come from 3 drop down lists: Subject, Author, Type.
What I'd like is when the user presses "Filter" it will take the selected values from the drop down lists and pass them to the querystring - it could be 1 value, 2, or all 3 (like above).
The drop down lists have an item called "All Subjects" / "All Author" / "All Type" each with a value of -1. The idea being that if the user leaves these items selected then the Filter button just ignores them.
Here is my code so far:
Protected Sub buttonFilterGo_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonFilterGo.Click
Dim queryString As String
Dim selectedAuthorString As String = "author=" & dropAuthorList.SelectedItem.Value
Dim selectedSubjectString As String = "subject=" & dropSubjectList.SelectedItem.Value
Dim selectedTypeString As String = "type=" & dropPaperType.SelectedItem.Value
Const PATH As String = "~/paper/browse/?"
queryString = selectedAuthorString & "&" & selectedSubjectString & "&" & selectedTypeString
If IsNothing(queryString) Then
labelFilterFeedback.Text = "Apply some filters then press Go"
Else
Response.Redirect(PATH & queryString)
labelFilterFeedback.Text = ""
End If
End Sub
Also, one more thing. How do I get the drop down lists to have the filters selected when the page re loads?
I'd really appreciate any help!
EDIT: I changed the default values of the drop down lists to "" - this leaves the URL looking messy though ?author=&subject=&type= This works, is it the best way?
I am not a VB person, so forgive any syntax errors. This approach will only add the query string if there are values, and only add terms for those parameters with values. I used "!="as the Not Equal operator. I am not sure if VB uses "<>" instead. Please consider this more as pseudo-code to illustrate the idea.
Dim queryString As String = "?"
...
Const PATH As String = "~/paper/browse/"
...
If dropAuthorList.SelectedItem.Value != "" Then
queryString = queryString & selectedAuthorString
EndIf
If dropSubjectList.SelectedItem.Value != "" Then
If querystring.Length > 1 Then
queryString = queryString + "&"
EndIf
queryString = queryString & selectedSubjectString
EndIf
If dropPaperType.SelectedItem.Value != "" Then
If querystring.Length > 1 Then
queryString = queryString + "&"
EndIf
queryString = queryString & selectedTypeString
EndIf
If querystring.Length = 1 Then
queryString = ""
EndIf
You can continue to use your empty string value and I would tend to prefer this to an assigned value, even though -1 is usually a good choice since it's highly unlikely that one of your filters would be using that as a value. I would clean up your query string though by calling something like the following function:
Private Function AppendFilter(ByVal filterName As String, ByVal filterVal As String, ByVal query As String) As String
Dim res As String = query
If filterVal.Length() > 0 Then
res = IIf(query.Length() > 0, query & "&", query) & filterName & "=" & filterVal
End If
Return res
End Function
instead of this line from your code: queryString = selectedAuthorString & "&" & selectedSubjectString & "&" & selectedTypeString
Your resulting code would look like this:
Protected Sub buttonFilterGo_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonFilterGo.Click
Dim queryString As String = ""
Const PATH As String = "~/paper/browse/?"
queryString = AppendFilter("author", dropAuthorList.SelectedItem.Value, queryString)
queryString = AppendFilter("subject", dropSubjectList.SelectedItem.Value, queryString)
queryString = AppendFilter("type", dropPaperType.SelectedItem.Value, queryString)
If queryString.Length() <= 0 Then
labelFilterFeedback.Text = "Apply some filters then press Go"
Else
Response.Redirect(PATH & "?" & queryString)
labelFilterFeedback.Text = ""
End If
End Sub
And your query string won't contain filters that aren't applicable.

Getting the Request Variables from an ASP.NET page

I wrote the following function that works about 95% of the time, but I need it to work 100% (obviously):
Public Shared Function getPassedVars() As String
Const keyCount As Integer = 54 ' 54 seems to be the number of parameter keys passed by default (for this web_app).
' there are more if there is a form involved (ie. from search page)
Dim oParams As String = ""
Try
With HttpContext.Current
If .Request.Params.AllKeys.Count > keyCount Then
For i As Integer = 0 To (.Request.Params.AllKeys.Count - (keyCount + 1))
oParams &= String.Format("{0}={1}{2}", .Request.Params.Keys.Item(i), .Request.Params(i), IIf(i < .Request.Params.AllKeys.Count - (keyCount + 1), ";", ""))
Next
End If
End With
Return oParams
Catch ex As Exception
Return Nothing
End Try
End Function
It scrubs the Request.Params object for passed variables, which are in the beginning of the array (the remaining ones are ASP parameters). I am pretty sure I've seen a different way to get these parameters, but I haven't been able to figure it out. Any suggestions?
EDIT
So it looks like I can use the Request.URL.Query to achieve this, I will investigate this and post back.
Here is what I came up with:
Public Shared Function getPassedVars() As String
Dim oParams As String = ""
Dim qString As String = ""
Dim oSplit As New List(Of String)
Try
With HttpContext.Current
qString = .Request.Url.Query
If qString.Length > 0 Then 'do we have any passed variables?
If qString.StartsWith("?") Then qString = qString.Remove(0, 1) 'remove leading ? from querystring if it is there
oSplit.AddRange(qString.Split("&"))
For i As Integer = 0 To oSplit.Count - 1
oParams &= String.Format("{0}{1}", oSplit.Item(i), IIf(i < oSplit.Count - 1, ";", ""))
Next
Return oParams
Else
Return Nothing
End If
End With
Catch ex As Exception
Return Nothing
End Try
End Function
So far so good.
Request.QueryString is a NameValueCollection, so the easiest way to get the "parameters" is to do the following:
foreach (String s in Request.QueryString) {
Response.Write(s + " = " + Request.QueryString[s]);
}
Where is your function located? If it's executing in the page's code behind then you definitely do not need to use the HttpContext variable.
It looks like you are trying to get values from the query string.
For example, for this URL:-
http://www.tempuri.org/mypage.aspx?param1=x&param2=y
I assume you want retreive the values of the query string parameters param1 and param2?
If so, just use:-
Dim param1 as String = Request.QueryString("param1")
Otherwise, if these parameters are contained in a form (an HTTP POST request) then use the method which Mitchel Sellers suggests.
If you know the name you can use the following to get it by key value
Dim myParamValue as String = Request.Form("MyKeyName")
Otherwise, you can loop through the form collection, by key etc, to get the values. The key is, do you really need to be parsing all 54 items? Or are you simply looking for a few specific values?
httpcontext.Current.Request.QueryString("KeyName")
Request.Params will contain the query parameters you're after.
There's no need to parse the info from Request.URL since it's already done for you.

Resources