简体   繁体   English

在 C# 中将查询字符串转换为字典的最佳方法

[英]Best way to convert query string to dictionary in C#

I'm looking for the simplest way of converting a query string from an HTTP GET request into a Dictionary, and back again.我正在寻找将查询字符串从 HTTP GET 请求转换为字典,然后再返回的最简单方法。

I figure it's easier to carry out various manipulations on the query once it is in dictionary form, but I seem to have a lot of code just to do the conversion.我认为一旦查询以字典形式对查询进行各种操作会更容易,但我似乎有很多代码只是为了进行转换。 Any recommended ways?有什么推荐的方法吗?

HttpUtility.ParseQueryString() parses query string into a NameValueCollection object, converting the latter to an IDictionary<string, string> is a matter of a simple foreach . HttpUtility.ParseQueryString()将查询字符串解析为NameValueCollection对象,将后者转换为IDictionary<string, string>是一个简单的foreach This, however, might be unnecessary since NameValueCollection has an indexer, so it behaves pretty much like a dictionary.然而,这可能是不必要的,因为NameValueCollection有一个索引器,所以它的行为非常像一个字典。

Here is how I usually do it这是我通常的做法

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

How about HttpUtility.ParseQueryString ? HttpUtility.ParseQueryString怎么HttpUtility.ParseQueryString

Just add a reference to System.Web.dll只需添加对 System.Web.dll 的引用

Same as Sean, but with Linq (and a function you can copy and paste):与 Sean 相同,但使用 Linq(以及您可以复制和粘贴的功能):

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

Also, the question asked how to get it back into a query string:此外,该问题询问如何将其恢复为查询字符串:

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

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

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

I like the brevity of Jon Canning's answer , but in the interest of variety, here is another alternative to his answer, that would also work for restricted environments like Windows Phone 8, that lack the HttpUtility.ParseQueryString() utility:我喜欢Jon Canning 答案的简洁性,但出于多样性的考虑,这里是他的答案的另一种替代方法,它也适用于 Windows Phone 8 等缺少HttpUtility.ParseQueryString()实用程序的受限环境:

    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;
    }

Actually, a useful improvement to Canning's answer that take care of decoding url-encoded values (like in the above solution) is:实际上,对 Canning's answer 的一个有用的改进是:

    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 ));
    }

In ASP.NET Core, use ParseQuery .在 ASP.NET Core 中,使用ParseQuery

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

一个没有 HttpUtility 的班轮

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

Yet another way to do it:另一种方法来做到这一点:

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));
}

Instead of converting HttpContext.Request.QueryString to Dictionary<> , try using不要HttpContext.Request.QueryString转换Dictionary<> ,而是尝试使用

HttpContext.Request.Query

which already is a Dictionary<string, StringValues>这已经是一个Dictionary<string, StringValues>

I stumbled across this post whilst looking for the same solution for an Azure WebJob, hopefully this helps others doing the same.我在为 Azure WebJob 寻找相同的解决方案时偶然发现了这篇文章,希望这可以帮助其他人做同样的事情。

If you are coding an Azure WebJob you use the GetQueryParameterDictionary() extension method.如果您正在编写 Azure WebJob,请使用GetQueryParameterDictionary()扩展方法。

var queryParameterDictionary = request.GetQueryParameterDictionary();

where request is of type HttpRequest and queryParameterDictionary is now of type IDictionary<string, string>其中requestHttpRequest类型,而queryParameterDictionary现在是IDictionary<string, string>

You can just get it by decorating the parameter with the FromQueryAttribute您可以通过使用FromQueryAttribute装饰参数来获取它

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

PS If you want to get multiple values for each key you can change the Dictionary to Dictionary<string, List<string>> PS 如果您想为每个键获取多个值,您可以将 Dictionary 更改为Dictionary<string, List<string>>

Most simple:最简单:

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]);
}

AspNet Core now automatically includes HttpRequest . Query AspNet Core 现在自动包含HttpRequest . Query HttpRequest . Query which can be used similar to a dictionary with key accessors.可以类似于带有键访问器的字典使用的HttpRequest . Query

However if you needed to cast it for logging or other purposes, you can pull out that logic into an extension method like this:但是,如果您需要将其转换为日志记录或其他目的,您可以将该逻辑提取到扩展方法中,如下所示:

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

Then, you can consume it on your httpRequest like this:然后,您可以像这样在 httpRequest 上使用它:

var params = httpRequest.Query.ToDictionary()

Further Reading进一步阅读

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM