【问题标题】:Best way to convert query string to dictionary in C#在 C# 中将查询字符串转换为字典的最佳方法
【发布时间】:2010-10-21 00:55:54
【问题描述】:

我正在寻找将查询字符串从 HTTP GET 请求转换为字典并再转换回来的最简单方法。

我认为一旦查询以字典形式执行各种操作会更容易,但我似乎有很多代码只是为了进行转换。有什么推荐的方法吗?

【问题讨论】:

    标签: c#


    【解决方案1】:

    AspNet Core 现在自动包含@987654321@.@987654322@,可以像使用带有键访问器的字典一样使用它。

    但是,如果您需要将其转换为日志记录或其他目的,您可以将该逻辑提取到扩展方法中,如下所示:

    public static class HttpRequestExtensions
    {
      public static Dictionary<string, string> ToDictionary(this IQueryCollection query)
      {
        return query.Keys.ToDictionary(k => k, v => (string)query[v]);
      }
    }
    

    然后,您可以像这样在 httpRequest 上使用它:

    var params = httpRequest.Query.ToDictionary()
    

    进一步阅读

    【讨论】:

      【解决方案2】:

      不要转换 HttpContext.Request.QueryStringDictionary&lt;&gt;,尝试使用

      HttpContext.Request.Query
      

      已经是Dictionary&lt;string, StringValues&gt;

      【讨论】:

        【解决方案3】:

        这是我通常的做法

        Dictionary<string, string> parameters = HttpContext.Current.Request.QueryString.Keys.Cast<string>()
            .ToDictionary(k => k, v => HttpContext.Current.Request.QueryString[v]);
        

        【讨论】:

        • 简单直接!值得 +1 :-)
        • 优雅的答案
        • 请注意,它们的键可以为空,这将导致语句失败。我通过将 ".ToDictionary(k => k,..." 更改为 ".ToDictionary(k => k ?? "", ..." 来修复它。(您可以使用任何默认的“k”值想要。)
        【解决方案4】:

        你可以通过用FromQueryAttribute装饰参数来获得它

        public void Action([FromQuery] Dictionary<string, string> queries)
        {
            ...
        }
        

        附:如果您想为每个键获取多个值,可以将 Dictionary 更改为 Dictionary&lt;string, List&lt;string&gt;&gt;

        【讨论】:

          【解决方案5】:

          我在为 Azure WebJob 寻找相同的解决方案时偶然发现了这篇文章,希望这可以帮助其他人做同样的事情。

          如果您正在编写 Azure WebJob,请使用 GetQueryParameterDictionary() 扩展方法。

          var queryParameterDictionary = request.GetQueryParameterDictionary();
          

          request 的类型为 HttpRequestqueryParameterDictionary 现在的类型为 IDictionary&lt;string, string&gt;

          【讨论】:

            【解决方案6】:

            在 ASP.NET Core 中,使用 ParseQuery

            var query = HttpContext.Request.QueryString.Value;
            var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
            

            【讨论】:

              【解决方案7】:

              最简单的:

              Dictionary<string, string> parameters = new Dictionary<string, string>();
              
              for (int i = 0; i < context.Request.QueryString.Count; i++)
              {
                  parameters.Add(context.Request.QueryString.GetKey(i), context.Request.QueryString[i]);
              }
              

              【讨论】:

              • 在您的代码段中添加描述,只是代码块不会有太大帮助。
              【解决方案8】:

              与 Sean 相同,但使用 Linq(以及可以复制和粘贴的功能):

              public static Dictionary<string, string> ParseQueryString(string queryString)
              {
                 var nvc = HttpUtility.ParseQueryString(queryString);
                 return nvc.AllKeys.ToDictionary(k => k, k => nvc[k]);
              }
              

              此外,问题还询问如何将其恢复为查询字符串:

              public static string CreateQueryString(Dictionary<string, string> parameters)
              {
                 return string.Join("&", parameters.Select(kvp => 
                    string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value))));
              }
              

              【讨论】:

                【解决方案9】:

                另一种方法:

                NameValueCollection nvcData = HttpUtility.ParseQueryString(queryString);
                Dictionary<string, string> dictData = new Dictionary<string, string>(nvcData.Count);
                foreach (string key in nvcData.AllKeys)
                {
                    dictData.Add(key, nvcData.Get(key));
                }
                

                【讨论】:

                  【解决方案10】:

                  没有 HttpUtility 的一个班轮

                  var dictionary = query.Replace("?", "").Split('&').ToDictionary(x => x.Split('=')[0], x => x.Split('=')[1]);
                  

                  【讨论】:

                  • 好的,我还没想到那个用例。您可以在.ToDictionary 之前添加.Where(x =&gt; !String.IsNullOrEmpty(x)) 以避免该异常
                  • 您可以简单地在 .Split('&') 中添加一个 StringSplitOptions.RemoveEmptyEntries 参数:.Split(new [] { '&' }, StringSplitOptions.RemoveEmptyEntries)
                  【解决方案11】:

                  我喜欢 Jon Canning's answer 的简洁性,但为了多样化,这是他答案的另一种选择,它也适用于缺少 HttpUtility.ParseQueryString() 实用程序的受限环境,如 Windows Phone 8:

                      public static Dictionary<string, string> ParseQueryString(String query)
                      {
                          Dictionary<String, String> queryDict = new Dictionary<string, string>();
                          foreach (String token in query.TrimStart(new char[] { '?' }).Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
                          {
                              string[] parts = token.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                              if (parts.Length == 2)
                                  queryDict[parts[0].Trim()] = HttpUtility.UrlDecode(parts[1]).Trim();
                              else
                                  queryDict[parts[0].Trim()] = "";
                          }
                          return queryDict;
                      }
                  

                  实际上,对处理 url 编码值(如上述解决方案)进行解码的 Canning 答案的一个有用改进是:

                      public static Dictionary<string, string> ParseQueryString2(String query)
                      {
                         return Regex.Matches(query, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => HttpUtility.UrlDecode( x.Groups[3].Value ));
                      }
                  

                  【讨论】:

                    【解决方案12】:

                    只需为单声道兼容解决方案执行此操作

                    Regex.Matches(queryString, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value)
                    

                    【讨论】:

                    • 也适用于 Windows Phone 8(HttpUtility.ParseQueryString 也不存在)。
                    • @BinaryWorrier 如果它们不是简单的 .GroupBy(x => x.Groups[1].Value).ToDictionary(g => g.Key, g => g.First( ).Groups[3].Value);可以工作(有明显的数据丢失)
                    • 这个答案对我来说是完美的,因为我在 Unity 中编写 C#。有点惊讶于那种环境的解决方案很难找到,但是哦。
                    • 顺便说一句,这段代码依赖于 'System.Linq' 和 'System.Text.RegularExpressions;'
                    【解决方案13】:

                    HttpUtility.ParseQueryString() 将查询字符串解析为NameValueCollection 对象,将后者转换为IDictionary&lt;string, string&gt; 是一个简单的foreach 的问题。然而,这可能是不必要的,因为NameValueCollection 有一个索引器,所以它的行为很像字典。

                    【讨论】:

                    • Request.QueryString 已经是一个 NameValueCollection,@H70 的答案是最容易放入字典 var parameters = Request.QueryString.Keys.Cast&lt;string&gt;().ToDictionary(k =&gt; k, v =&gt; Request.QueryString[v]);
                    • 我刚刚尝试使用它,我认为它有一个问题:结果NameValueCollection 值在迭代时被静默修改。例如,尝试调用var q = HttpUtility.ParseQueryString("firstParam=cGFzc35+d29yZA==")(这是字符串pass~~word 的base64 编码),然后使用for (var i = 0; i &lt;= q.Keys.Count; ++i) { var val = q[q.Keys[i]]; } 对其进行迭代。查看val 的值:您将获得cGFzc35 d29yZA== 而不是cGFzc35+d29yZA==
                    【解决方案14】:

                    HttpUtility.ParseQueryString怎么样?

                    只需添加对 System.Web.dll 的引用

                    【讨论】:

                      猜你喜欢
                      • 2014-06-28
                      • 2014-06-21
                      • 2011-05-09
                      • 2014-01-28
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-10-10
                      • 2020-02-08
                      相关资源
                      最近更新 更多