I was trying to fetch the Name/Value of a querystring using For Each loop, as per @kloarubeek answer shown in → Request.Querystring(variablevalue) possible? as follows:
For Each Item in Request.QueryString
Response.Write Item & ": " & Request.QueryString(Item) & "<br/>"
Next
But it returns the items not in the order sent, for example:
if my queryString is:
"Item1=1&Item2=2&Item3=3&Item4=4"
then the For Each Loop returns:
Item1=1
Item3=3
Item2=2
Item4=4
I managed to work around it by splitting it into an Array and then loop inside this array and re-split each item again into name and value. but it's a long and not very efficient coding.
So is there a better and shorter way to fetch the querystring's name/value
using the For Each Loop
but in the same order
?
Your for each
statement should loop through the query strings in the order they were passed, it's very strange that it doesn't, I'd never heard of that before. But as your parameters are numbered you can assign them to an array and reorder based on their numerical indicators.
This is how I would tackle this issue, I don't know if it's shorter than your method of splitting and reordering, but it does seem to be efficient:
<%
if request.querystring.count > 0 then
Dim lookFor, queryStrings(), items(), x, y
' Specify the query string name to find and reorder. The name should have a numeric suffix.
lookFor = "item" ' Looking for item1, item2, item3, item4 etc...
' Create a 2d array, set the upperbound value to match the number of query strings passed.
ReDim queryStrings(request.querystring.count-1,1)
' Loop through each query string.
x = 0 : for each item in request.querystring
' We're only interested in query strings where the name starts with "item". Use inStr()
' with a textual comparison to check, and use replace() to check that the item name has
' a numeric suffix.
if inStr(1,item,lookFor,1) = 1 AND isNumeric(replace(item,lookFor,"",1,-1,1)) then
' Only store the number part of the query string name. This is needed for reordering later.
queryStrings(x,0) = int(replace(item,lookFor,"",1,-1,1))
queryStrings(x,1) = request.querystring(item)
x = x + 1
end if
Next
' The queryStrings array may contain empty values. We can't use "ReDim Preserve" to resize
' a 2d array, so instead let's create another 2d array and set the upperbound value to the
' number of items found.
ReDim items(x-1,1)
' Assign the non-empty data from the queryStrings array to the items array.
y = 0 : for x = 0 to uBound(queryStrings)
if NOT isEmpty(queryStrings(x,0)) then
items(y,0) = queryStrings(x,0)
items(y,1) = queryStrings(x,1)
y = y + 1
end if
next
' Reorder the items array.
Dim temp0, temp1
for x = uBound(items)-1 to 0 step-1
for y = 0 to x
if items(y,0) > items(y+1,0) then
temp0 = items(y+1,0)
temp1 = items(y+1,1)
items(y+1,0) = items(y,0)
items(y+1,1) = items(y,1)
items(y,0) = temp0
items(y,1) = temp1
end if
next
next
' Finally, output the reordered items array.
for x = 0 to uBound(items)
response.write lookFor & items(x,0) & ": " & items(x,1) & "<br>"
next
end if
%>
Let's take a completely jumbled up query string order:
?Item3=3
&Item6=6
&Item2=2
&Item7=7
&Item4=4
&Item1=1
&Item5=5
Output:
item1: 1
item2: 2
item3: 3
item4: 4
item5: 5
item6: 6
item7: 7
Let's do the same, but throw in some additional parameters:
?foo1=bar1
&Item2=2
&foo2=bar2
&Item5=5
&Item1=1
&Item3=3
&Item4=4
&foo3=bar3
Output:
item1: 1
item2: 2
item3: 3
item4: 4
item5: 5
The additional parameters are ignored
Finally, let's pass some duplicate parameters:
?Item2=2
&Item4=Four
&Item5=5
&Item1=1
&Item2=Two
&Item3=3
&Item4=4
Output:
item1: 1
item2: 2, Two
item3: 3
item4: Four, 4
item5: 5
EDIT: I assumed the fault was with IIS or ASP reordering the querystring header (somehow?), but after seeing your comment where you said if I target the querystring with the index number it gets the order right
the headers are obviously correct and the fault lies within the for each
method (as outlined in the other answer). A much simpler solution would be to split the raw querystring header yourself (rather than using for each
) and loop through looking for the items:
<%
Dim splitQS, reSplitQS, x, lookFor : lookFor = "item"
splitQS = split(Request.QueryString,"&")
for x = 0 to uBound(splitQS)
reSplitQS = split(splitQS(x),"=")
if uBound(reSplitQS) = 1 then
if inStr(1,reSplitQS(0),lookFor,1) = 1 then
response.write reSplitQS(0) & ": " &_
request.QueryString(reSplitQS(0)) & "<br>"
end if
end if
next
%>