从 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] 将返回真实或虚构片段的左侧。以下是关于 queryfragment 放置的规范: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 一样,因为它是静态的并且可以重复使用。 我将正则表达式更新为@"[?&amp;](\w[\w.]*)=([^?&amp;]+)",因为[|?]&amp; 也匹配|[^?|^&amp;] 匹配除? / | / ^&amp; 之外的任何字符。 【参考方案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 [重复]

express 无法从 url 获取查询参数 [重复]

从URI获取真实路径,Android KitKat新的存储访问框架[重复]

通过使用查询而不是重复观察单个事件来加快获取我的社交网络应用程序的帖子

通过使用查询而不是重复观察单个事件来加快获取我的社交网络应用程序的帖子