如何使用 For Each Loop 获取 Name/Value of Request.Querystring 但发送顺序相同?
How to fetch Name/Value of Request.Querystring using For Each Loop but in the same order sent?
我试图使用 For Each 循环获取查询字符串的 Name/Value,根据 @kloarubeek 显示的答案在 → Request.Querystring(variablevalue) possible? 中如下:
For Each Item in Request.QueryString
Response.Write Item & ": " & Request.QueryString(Item) & "<br/>"
Next
但是returns物品不在发送顺序,例如:
如果我的 queryString 是:
"Item1=1&Item2=2&Item3=3&Item4=4"
然后 For Each Loop returns:
Item1=1
Item3=3
Item2=2
Item4=4
我设法通过将它拆分为一个 数组 来解决它,然后在这个数组中循环并 再次重新拆分每个项目成名称和价值。但这是一个很长而且效率不高的编码。
那么有没有更好更短的方法来获取 querystring's name/value
使用 For Each Loop
但 in the same order
?
QueryString 对象是一个 NameValueCollection,根据 MSDN:
Collections of this type do not preserve the ordering of elements, and no particular ordering is guaranteed when enumerating the collection.
因此它不支持按与 url 相同的顺序获取它。
编辑以添加一个选项:
话虽这么说,但看起来唯一的方法就是解析 url。在这个 Whosebug 问题 (Get individual query parameters from Uri) 中,其中一个答案包括使用正则表达式对其进行解析的部分(那里的所有其他答案都导致相同的 NameValueCollection)。您需要稍微修改一下,因为 Dictionary class 也有不遵守顺序的问题。我会把它改成这样:
public static class UriExtensions
{
private static readonly Regex _regex = new Regex(@"[?&](\w[\w.]*)=([^?&]+)");
public static List<KeyValuePair<string, string>> ParseQueryString(this Uri uri)
{
var match = _regex.Match(uri.PathAndQuery);
var paramaters = new List<KeyValuePair<string, string>>();
while (match.Success)
{
paramaters.Add(new KeyValuePair(match.Groups[1].Value, match.Groups[2].Value));
match = match.NextMatch();
}
return paramaters;
}
}
要这样称呼它:
Request.Url.ParseQueryString()
我会注意到我自己还没有测试过这个方法,并且我认为它在另一个问题上被认为是一个很好的答案。
https://docs.microsoft.com/en-us/dotnet/api/system.web.httprequest.querystring?view=netframework-4.7.2
https://docs.microsoft.com/en-us/dotnet/api/system.collections.specialized.namevaluecollection?view=netframework-4.7.2
您的 for each
语句应该按照传递的顺序遍历查询字符串,很奇怪它没有,我以前从未听说过。但是由于您的参数已编号,您可以将它们分配给一个数组并根据它们的数字指示符重新排序。
这就是我解决这个问题的方法,我不知道它是否比你的拆分和重新排序的方法更短,但它看起来确实有效:
<%
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
%>
让我们来看一个完全混乱的查询字符串顺序:
?Item3=3
&Item6=6
&Item2=2
&Item7=7
&Item4=4
&Item1=1
&Item5=5
输出:
item1: 1
item2: 2
item3: 3
item4: 4
item5: 5
item6: 6
item7: 7
让我们做同样的事情,但加入一些额外的参数:
?foo1=bar1
&Item2=2
&foo2=bar2
&Item5=5
&Item1=1
&Item3=3
&Item4=4
&foo3=bar3
输出:
item1: 1
item2: 2
item3: 3
item4: 4
item5: 5
忽略附加参数
最后,让我们传递一些重复的参数:
?Item2=2
&Item4=Four
&Item5=5
&Item1=1
&Item2=Two
&Item3=3
&Item4=4
输出:
item1: 1
item2: 2, Two
item3: 3
item4: Four, 4
item5: 5
编辑: 我假设错误是 IIS 或 ASP 重新排序查询字符串 header (不知何故?),但之后看到你说 if I target the querystring with the index number it gets the order right
的评论,header 显然是正确的,错误在于 for each
方法(如其他答案中所述)。一个更简单的解决方案是自己拆分原始查询字符串 header(而不是使用 for each
)并循环查找项目:
<%
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
%>
我试图使用 For Each 循环获取查询字符串的 Name/Value,根据 @kloarubeek 显示的答案在 → Request.Querystring(variablevalue) possible? 中如下:
For Each Item in Request.QueryString
Response.Write Item & ": " & Request.QueryString(Item) & "<br/>"
Next
但是returns物品不在发送顺序,例如:
如果我的 queryString 是:
"Item1=1&Item2=2&Item3=3&Item4=4"
然后 For Each Loop returns:
Item1=1
Item3=3
Item2=2
Item4=4
我设法通过将它拆分为一个 数组 来解决它,然后在这个数组中循环并 再次重新拆分每个项目成名称和价值。但这是一个很长而且效率不高的编码。
那么有没有更好更短的方法来获取 querystring's name/value
使用 For Each Loop
但 in the same order
?
QueryString 对象是一个 NameValueCollection,根据 MSDN:
Collections of this type do not preserve the ordering of elements, and no particular ordering is guaranteed when enumerating the collection.
因此它不支持按与 url 相同的顺序获取它。
编辑以添加一个选项:
话虽这么说,但看起来唯一的方法就是解析 url。在这个 Whosebug 问题 (Get individual query parameters from Uri) 中,其中一个答案包括使用正则表达式对其进行解析的部分(那里的所有其他答案都导致相同的 NameValueCollection)。您需要稍微修改一下,因为 Dictionary class 也有不遵守顺序的问题。我会把它改成这样:
public static class UriExtensions
{
private static readonly Regex _regex = new Regex(@"[?&](\w[\w.]*)=([^?&]+)");
public static List<KeyValuePair<string, string>> ParseQueryString(this Uri uri)
{
var match = _regex.Match(uri.PathAndQuery);
var paramaters = new List<KeyValuePair<string, string>>();
while (match.Success)
{
paramaters.Add(new KeyValuePair(match.Groups[1].Value, match.Groups[2].Value));
match = match.NextMatch();
}
return paramaters;
}
}
要这样称呼它:
Request.Url.ParseQueryString()
我会注意到我自己还没有测试过这个方法,并且我认为它在另一个问题上被认为是一个很好的答案。
https://docs.microsoft.com/en-us/dotnet/api/system.web.httprequest.querystring?view=netframework-4.7.2 https://docs.microsoft.com/en-us/dotnet/api/system.collections.specialized.namevaluecollection?view=netframework-4.7.2
您的 for each
语句应该按照传递的顺序遍历查询字符串,很奇怪它没有,我以前从未听说过。但是由于您的参数已编号,您可以将它们分配给一个数组并根据它们的数字指示符重新排序。
这就是我解决这个问题的方法,我不知道它是否比你的拆分和重新排序的方法更短,但它看起来确实有效:
<%
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
%>
让我们来看一个完全混乱的查询字符串顺序:
?Item3=3
&Item6=6
&Item2=2
&Item7=7
&Item4=4
&Item1=1
&Item5=5
输出:
item1: 1
item2: 2
item3: 3
item4: 4
item5: 5
item6: 6
item7: 7
让我们做同样的事情,但加入一些额外的参数:
?foo1=bar1
&Item2=2
&foo2=bar2
&Item5=5
&Item1=1
&Item3=3
&Item4=4
&foo3=bar3
输出:
item1: 1
item2: 2
item3: 3
item4: 4
item5: 5
忽略附加参数
最后,让我们传递一些重复的参数:
?Item2=2
&Item4=Four
&Item5=5
&Item1=1
&Item2=Two
&Item3=3
&Item4=4
输出:
item1: 1
item2: 2, Two
item3: 3
item4: Four, 4
item5: 5
编辑: 我假设错误是 IIS 或 ASP 重新排序查询字符串 header (不知何故?),但之后看到你说 if I target the querystring with the index number it gets the order right
的评论,header 显然是正确的,错误在于 for each
方法(如其他答案中所述)。一个更简单的解决方案是自己拆分原始查询字符串 header(而不是使用 for each
)并循环查找项目:
<%
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
%>