从 Uri 获取单个查询参数 [重复]
Posted
技术标签:
【中文标题】从 Uri 获取单个查询参数 [重复]【英文标题】:Get individual query parameters from Uri [duplicate] 【发布时间】:2011-02-22 11:53:38 【问题描述】:我有一个 uri 字符串,例如:http://example.com/file?a=1&b=2&c=string%20param
是否存在将查询参数字符串转换为字典的现有函数,其方式与 ASP.NET Context.Request 相同。
我正在编写控制台应用程序而不是 Web 服务,因此没有 Context.Request 来为我解析 URL。
我知道自己破解查询字符串很容易,但如果存在,我宁愿使用 FCL 函数。
【问题讨论】:
【参考方案1】:使用这个:
string uri = ...;
string queryString = new System.Uri(uri).Query;
var queryDictionary = System.Web.HttpUtility.ParseQueryString(queryString);
Tejs 的这段代码不是从 URI 获取查询字符串的“正确”方式:
string.Join(string.Empty, uri.Split('?').Skip(1));
【讨论】:
请注意,Uri.Query
仅适用于绝对 Uri。相对而言,它会抛出一个InvalidOperationExeception
。
一旦从Uri
得到Query
,就可以使用HttpUtility.ParseQueryString(uri.Query)
获取名称值集合【参考方案2】:
你可以使用:
var queryString = url.Substring(url.IndexOf('?')).Split('#')[0]
System.Web.HttpUtility.ParseQueryString(queryString)
MSDN
【讨论】:
但您需要添加对System.Web.dll
的引用。
正如另一个答案所说,ParseQueryString 将添加 'example.com/file?a' 作为第一个键。
更新了新代码。奇怪的是,这个答案似乎很受欢迎。
要记住的另一件事,ParseQueryString 总是在解析时执行 UrlDecode,只要你没有任何依赖于一对一相似性的东西,比如签名算法在 SAML 重定向绑定中,该绑定在另一侧计算签名后编码等。
Split('#')[0]
将返回真实或虚构片段的左侧。以下是关于 query 的 fragment 放置的规范:RFC 3986【参考方案3】:
这应该可行:
string url = "http://example.com/file?a=1&b=2&c=string%20param";
string querystring = url.Substring(url.IndexOf('?'));
System.Collections.Specialized.NameValueCollection parameters =
System.Web.HttpUtility.ParseQueryString(querystring);
根据MSDN。不是您正在寻找的确切集合类型,但仍然很有用。
编辑:显然,如果您将完整的 url 提供给 ParseQueryString
,它将添加 'http://example.com/file?a' 作为集合的第一个键。由于这可能不是您想要的,因此我添加了子字符串以仅获取 url 的相关部分。
【讨论】:
【参考方案4】:我必须为现代 Windows 应用程序执行此操作。我使用了以下内容:
public static class UriExtensions
private static readonly Regex _regex = new Regex(@"[?&](\w[\w.]*)=([^?&]+)");
public static IReadOnlyDictionary<string, string> ParseQueryString(this Uri uri)
var match = _regex.Match(uri.PathAndQuery);
var paramaters = new Dictionary<string, string>();
while (match.Success)
paramaters.Add(match.Groups[1].Value, match.Groups[2].Value);
match = match.NextMatch();
return paramaters;
【讨论】:
@Ross Dargan:这是一个不错的解决方案,但我建议使用RegexOptions.Compiled
创建正则表达式对象,就像 this documentation 一样,因为它是静态的并且可以重复使用。
我将正则表达式更新为@"[?&](\w[\w.]*)=([^?&]+)"
,因为[|?]&
也匹配|
和[^?|^&]
匹配除?
/ |
/ ^
和&
之外的任何字符。
【参考方案5】:
看看HttpUtility.ParseQueryString()它会给你一个NameValueCollection
而不是字典,但仍然应该满足你的需要。
另一个选项是使用string.Split()
。
string url = @"http://example.com/file?a=1&b=2&c=string%20param";
string[] parts = url.Split(new char[] '?','&');
///parts[0] now contains http://example.com/file
///parts[1] = "a=1"
///parts[2] = "b=2"
///parts[3] = "c=string%20param"
【讨论】:
【参考方案6】:对于必须将依赖项保持在最低限度的独立项目,我发现自己使用了这个实现:
var arguments = uri.Query
.Substring(1) // Remove '?'
.Split('&')
.Select(q => q.Split('='))
.ToDictionary(q => q.FirstOrDefault(), q => q.Skip(1).FirstOrDefault());
但是请注意,我确实不处理任何类型的编码字符串,因为我在受控设置中使用它,其中编码问题将是服务器端的编码错误,应该修复。
【讨论】:
返回的参数解码不正确。 这正是我在代码@user2864740 下方写的内容? :) 现在试着再强调一点。【参考方案7】:在一行代码中:
string xyz = Uri.UnescapeDataString(HttpUtility.ParseQueryString(Request.QueryString.ToString()).Get("XYZ"));
【讨论】:
【参考方案8】:Microsoft Azure 提供了一个框架,可以轻松执行此操作。 http://azure.github.io/azure-mobile-services/ios/v2/Classes/MSTable.html#//api/name/readWithQueryString:completion:
【讨论】:
【参考方案9】:您可以在控制台应用程序中引用 System.Web,然后查找拆分 URL 参数的实用程序函数。
【讨论】:
以上是关于从 Uri 获取单个查询参数 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中获取请求:- 'String' 不能分配给参数类型'Uri' [重复]
如何从相应的 Ringtonemanager 获取铃声 URI [重复]
从URI获取真实路径,Android KitKat新的存储访问框架[重复]