关于解析:如何将查询字符串解析为.NET中的NameValueCollection

关于解析:如何将查询字符串解析为.NET中的NameValueCollection

How to parse a query string into a NameValueCollection in .NET

我想将诸如p1=6&p2=7&p3=8之类的字符串解析为NameValueCollection

当您无权访问Page.Request对象时,最优雅的方法是什么?


为此有一个内置的.NET实用程序:HttpUtility.ParseQueryString

1
2
// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
1
2
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)

您可能需要用new Uri(fullUrl).Query替换querystring


只要您在Web应用程序中,或者不介意包括对System.Web的依赖关系,HttpUtility.ParseQueryString都可以工作。另一种方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
NameValueCollection queryParameters = new NameValueCollection();
string[] querySegments = queryString.Split('&');
foreach(string segment in querySegments)
{
   string[] parts = segment.Split('=');
   if (parts.Length > 0)
   {
      string key = parts[0].Trim(new char[] { '?', ' ' });
      string val = parts[1].Trim();

      queryParameters.Add(key, val);
   }
}

由于接受的答案依赖于System.Web,因此许多答案都提供了自定义示例。从Microsoft.AspNet.WebApi.Client NuGet包中,可以使用UriExtensions.ParseQueryString方法,该方法也可以使用:

1
2
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();

因此,如果您想避免System.Web依赖性并且不想自己滚动,这是一个不错的选择。


我想删除对System.Web的依赖关系,以便我可以解析ClickOnce部署的查询字符串,同时前提条件仅限于"仅客户端框架子集"。

我喜欢rp的答案。我添加了一些其他逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static NameValueCollection ParseQueryString(string s)
    {
        NameValueCollection nvc = new NameValueCollection();

        // remove anything other than query string from url
        if(s.Contains("?"))
        {
            s = s.Substring(s.IndexOf('?') + 1);
        }

        foreach (string vp in Regex.Split(s,"&"))
        {
            string[] singlePair = Regex.Split(vp,"=");
            if (singlePair.Length == 2)
            {
                nvc.Add(singlePair[0], singlePair[1]);
            }
            else
            {
                // only one key with no value specified in query string
                nvc.Add(singlePair[0], string.Empty);
            }
        }

        return nvc;
    }

要在没有System.Web的情况下,无需自己编写并且没有其他NuGet软件包的情况下执行此操作:

  • 添加对System.Net.Http.Formatting的引用
  • 添加using System.Net.Http;
  • 使用此代码:

    1
    new Uri(uri).ParseQueryString()
  • https://msdn.microsoft.com/zh-CN/library/system.net.http.uriextensions(v=vs.118).aspx


    我需要一个比使用OLSC查询时已经提供的功能更加通用的功能。

    • 值可能包含多个等号
    • 解码名称和值中的编码字符
    • 能够在客户端框架上运行
    • 能够在Mobile Framework上运行。

    这是我的解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Public Shared Function ParseQueryString(ByVal uri As Uri) As System.Collections.Specialized.NameValueCollection
        Dim result = New System.Collections.Specialized.NameValueCollection(4)
        Dim query = uri.Query
        If Not String.IsNullOrEmpty(query) Then
            Dim pairs = query.Substring(1).Split("&"c)
            For Each pair In pairs
                Dim parts = pair.Split({"="c}, 2)

                Dim name = System.Uri.UnescapeDataString(parts(0))
                Dim value = If(parts.Length = 1, String.Empty,
                    System.Uri.UnescapeDataString(parts(1)))

                result.Add(name, value)
            Next
        End If
        Return result
    End Function

    在此基础上添加以向Uri本身添加功能也可能不是一个坏主意。


    如果要避免使用HttpUtility.ParseQueryString所需的对System.Web的依赖,可以使用在System.Net.Http中找到的Uri扩展方法ParseQueryString

    确保在项目中添加对System.Net.Http的引用(如果尚未添加)。

    请注意,您必须将响应主体转换为有效的Uri,以便ParseQueryString(在System.Net.Http中)起作用。

    1
    2
    3
    4
    5
    string body ="value1=randomvalue1&value2=randomValue2";

    //"http://localhost/query?" is added to the string"body" in order to create a valid Uri.
    string urlBody ="http://localhost/query?" + body;
    NameValueCollection coll = new Uri(urlBody).ParseQueryString();

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        private void button1_Click( object sender, EventArgs e )
        {
            string s = @"p1=6&p2=7&p3=8";
            NameValueCollection nvc = new NameValueCollection();

            foreach ( string vp in Regex.Split( s,"&" ) )
            {
                string[] singlePair = Regex.Split( vp,"=" );
                if ( singlePair.Length == 2 )
                {
                    nvc.Add( singlePair[ 0 ], singlePair[ 1 ] );    
                }    
            }
        }

    我刚刚意识到Web API客户端具有ParseQueryString扩展方法,该方法可在Uri上工作并返回HttpValueCollection

    1
    2
    var parameters = uri.ParseQueryString();
    string foo = parameters["foo"];

    只需访问Request.QueryString。作为另一个答案提到的AllKeys只会为您提供一系列的键。


    HttpUtility.ParseQueryString(Request.Url.Query)返回为HttpValueCollection(内部类)。它从NameValueCollection继承。

    1
    2
    3
    4
    5
    6
    7
    8
        var qs = HttpUtility.ParseQueryString(Request.Url.Query);
        qs.Remove("foo");

        string url ="~/Default.aspx";
        if (qs.Count > 0)
           url = url +"?" + qs.ToString();

        Response.Redirect(url);

    由于每个人似乎都在粘贴他的解决方案..这是我的:-)
    我需要一个不带System.Web的类库来从存储的超链接中获取id参数。

    以为我会分享,因为我发现此解决方案更快,外观更好。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public static class Statics
        public static Dictionary<string, string> QueryParse(string url)
        {
            Dictionary<string, string> qDict = new Dictionary<string, string>();
            foreach (string qPair in url.Substring(url.IndexOf('?') + 1).Split('&'))
            {
                string[] qVal = qPair.Split('=');
                qDict.Add(qVal[0], Uri.UnescapeDataString(qVal[1]));
            }
            return qDict;
        }

        public static string QueryGet(string url, string param)
        {
            var qDict = QueryParse(url);
            return qDict[param];
        }
    }

    用法:

    1
    Statics.QueryGet(url,"id")

    如果您不希望System.Web依赖项,只需从HttpUtility类粘贴此源代码。

    我只是从Mono的源代码中总结了这一点。它包含HttpUtility及其所有依赖项(例如IHtmlString,Helpers,HttpEncoder,HttpQSCollection)。

    然后使用HttpUtility.ParseQueryString

    https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c


    选中Request.QueryString.Keys以获取所有查询字符串参数的NameValueCollection。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    let search = window.location.search;

    console.log(search);

    let qString = search.substring(1);

    while(qString.indexOf("+") !== -1)

       qString  = qString.replace("+","");

    let qArray = qString.split("&");

    let values = [];

    for(let i = 0; i < qArray.length; i++){
       let pos = qArray[i].search("=");
       let keyVal = qArray[i].substring(0, pos);
       let dataVal = qArray[i].substring(pos + 1);
       dataVal = decodeURIComponent(dataVal);
       values[keyVal] = dataVal;
    }

    要获取所有Querystring值,请尝试以下操作:

    1
    2
    3
    4
    5
    6
    7
    8
        Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)

    Dim sb As New StringBuilder("<br />")
    For Each s As String In qscoll.AllKeys

      Response.Write(s &" -" & qscoll(s) &"<br />")

    Next s

    1
    2
            var q = Request.QueryString;
            NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());

    我在VB中翻译成乔什·布朗的C#版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private System.Collections.Specialized.NameValueCollection ParseQueryString(Uri uri)
    {
        var result = new System.Collections.Specialized.NameValueCollection(4);
        var query = uri.Query;
        if (!String.IsNullOrEmpty(query))
        {
            var pairs = query.Substring(1).Split("&".ToCharArray());
            foreach (var pair in pairs)
            {
                var parts = pair.Split("=".ToCharArray(), 2);
                var name = System.Uri.UnescapeDataString(parts[0]);
                var value = (parts.Length == 1) ? String.Empty : System.Uri.UnescapeDataString(parts[1]);
                result.Add(name, value);
            }
        }
        return result;
    }

    这是我的代码,我认为它非常有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public String GetQueryString(string ItemToRemoveOrInsert = null, string InsertValue = null )
    {
        System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
        if (ItemToRemoveOrInsert != null)
        {
            filtered.Remove(ItemToRemoveOrInsert);
            if (!string.IsNullOrWhiteSpace(InsertValue))
            {
                filtered.Add(ItemToRemoveOrInsert, InsertValue);
            }
        }

        string StrQr = string.Join("&", filtered.AllKeys.Select(key => key +"=" + filtered[key]).ToArray());
        if (!string.IsNullOrWhiteSpace(StrQr)){
            StrQr="?" + StrQr;
        }

        return StrQr;
    }


    推荐阅读

      linux查询命令进程?

      linux查询命令进程?,系统,名称,总量,情况,状态,进程,材料,工具,电脑,数据,怎

      查询linux内存命令?

      查询linux内存命令?,系统,情况,信息,工具,电脑,状态,命令,内存,发行,总量,查

      linux命令查询屏保?

      linux命令查询屏保?,系统,工作,工具,信息,地址,图片,命令,目录,基础,电脑,lin

      linux查询线程命令?

      linux查询线程命令?,系统,第一,线程,命令,进程,代码,分时,软件,选项,界面,如

      linux查询ip命令?

      linux查询ip命令?,地址,网络,信息,设备,系统,电脑,终端,命令,中心,技术指标,l

      linux查询所有命令?

      linux查询所有命令?,工作,地址,系统,命令,信息,目录,工具,基础,文件,内容,lin

      linux日志命令查询?

      linux日志命令查询?,系统,名称,信息,实时,电脑,对比,最新,日志,命令,环境,Lin

      linux命令解析dns?

      linux命令解析dns?,地址,系统,服务,网络,信息,状态,服务器,企业,管理,分析,Li

      linux文本查询命令?

      linux文本查询命令?,标准,命令,文件,工具,数据,信息,位置,系统,内容,文本,Lin

      命令查询linux包安装?

      命令查询linux包安装?,软件,地方,地址,名字,系统,名称,信息,路径,命令,文件,

      字符串查找命令linux?

      字符串查找命令linux?,系统,字符串,工具,信息,文件,命令,字符,选项,文本,范

      查询linux的命令历史?

      查询linux的命令历史?,信息,系统,名称,地址,服务,命令,数据,环境,指令,用户,

      linux线程查询命令?

      linux线程查询命令?,系统,第一,线程,命令,软件,名称,信息,进程,选项,方法,Lin

      linux命令左右查询?

      linux命令左右查询?,系统,信息,管理,地址,工作,命令,文件,单位,位置,数据,lin

      linux简单查询命令?

      linux简单查询命令?,地址,命令,信息,设备,电脑,系统,工作,文件,终端,内容,Lin

      linux线程查询命令?

      linux线程查询命令?,系统,第一,线程,命令,软件,名称,信息,进程,选项,方法,Lin

      linux命令左右查询?

      linux命令左右查询?,系统,信息,管理,地址,工作,命令,文件,单位,位置,数据,lin

      linux简单查询命令?

      linux简单查询命令?,地址,命令,信息,设备,电脑,系统,工作,文件,终端,内容,Lin

      查询linux配置的命令?

      查询linux配置的命令?,系统,网络,地址,情况,信息,电脑,中科,状态,服务,命令,

      linuxid命令解析?

      linuxid命令解析?,系统,工作,信息,密码,命令,工具,软件,电脑,情况,标准,linux