it-swarm-vi.tech

Cách phân tích chuỗi truy vấn thành NameValueCollection trong .NET

Tôi muốn phân tích một chuỗi như p1=6&p2=7&p3=8 thành một NameValueCollection.

Cách thức thanh lịch nhất để làm điều này khi bạn không có quyền truy cập vào đối tượng Page.Request là gì?

181
Nathan Smith

Có một tiện ích .NET tích hợp sẵn cho việc này: HttpUtility.PudeQueryString

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

Bạn có thể cần thay thế querystring bằng new Uri(fullUrl).Query.

348
Guy Starbuck

HttpUtility.PudeQueryString sẽ hoạt động miễn là bạn đang ở trong một ứng dụng web hoặc không bận tâm bao gồm cả sự phụ thuộc vào System.Web. Một cách khác để làm điều này là:

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);
   }
}
43
Scott Dorman

Rất nhiều câu trả lời đang cung cấp các ví dụ tùy chỉnh vì sự phụ thuộc của câu trả lời được chấp nhận vào System.Web . Từ Microsoft.AspNet.WebApi.Client Gói NuGet có riExtensions.PudeQueryString , phương thức cũng có thể được sử dụng:

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

Vì vậy, nếu bạn muốn tránh System.Web phụ thuộc và không muốn tự mình thực hiện, đây là một lựa chọn tốt.

25
James Skimming

Tôi muốn loại bỏ sự phụ thuộc vào System.Web để tôi có thể phân tích chuỗi truy vấn của triển khai ClickOnce, trong khi có các điều kiện tiên quyết giới hạn trong "Tập hợp khung chỉ dành cho khách hàng".

Tôi thích câu trả lời của rp. Tôi đã thêm một số logic bổ sung.

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

Tôi cần một chức năng linh hoạt hơn một chút so với những gì đã được cung cấp khi làm việc với các truy vấn OLSC.

  • Các giá trị có thể chứa nhiều dấu bằng
  • Giải mã các ký tự được mã hóa theo cả tên và giá trị
  • Có khả năng chạy trên Khung khách hàng
  • Có khả năng chạy trên Mobile Framework.

Đây là giải pháp của tôi:

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

Nó có thể không phải là một ý tưởng tồi để giải quyết <Extension()> về điều đó để thêm khả năng cho chính Uri.

7
Josh Brown

Để thực hiện việc này mà không cần System.Web, mà không cần tự viết và không có các gói NuGet bổ sung:

  1. Thêm một tham chiếu đến System.Net.Http.Formatting
  2. Thêm using System.Net.Http;
  3. Sử dụng mã này:

    new Uri(uri).ParseQueryString()
    

https://msdn.Microsoft.com/en-us/l Library/system.net.http.uriextensions (v = vs.118) .aspx

7
jvenema

Tôi mới nhận ra rằng Máy khách API Web có phương thức mở rộng ParseQueryString hoạt động trên Uri và trả về HttpValueCollection:

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

Nếu bạn muốn tránh sự phụ thuộc vào System.Web bắt buộc phải sử dụng HttpUtility.PudeQueryString , bạn có thể sử dụng phương thức mở rộng UriParseQueryString được tìm thấy trong System.Net.Http .

Đảm bảo thêm một tham chiếu (nếu bạn chưa có) vào System.Net.Http trong dự án của bạn.

Lưu ý rằng bạn phải chuyển đổi nội dung phản hồi thành Uri hợp lệ để ParseQueryString (trong System.Net.Http) hoạt động.

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();
2
Amadeus Sánchez
    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 ] );    
            }    
        }
    }
2
rp.

Chỉ cần truy cập Request.QueryString. AllKeys được đề cập như một câu trả lời khác chỉ giúp bạn có một loạt các khóa.

1
Bloodhound

Nếu bạn không muốn phụ thuộc System.Web, chỉ cần dán mã nguồn này từ lớp HttpUtility.

Tôi vừa đánh cái này từ mã nguồn của Mono . Nó chứa httpUtility và tất cả các phụ thuộc của nó (như IHtmlString, Helpers, HttpEncoder, HttpQSCollection).

Sau đó sử dụng HttpUtility.ParseQueryString.

https://Gist.github.com/bjorn-ALi-goransson/b04a7c44808bb2de8cca3fc9a3762f9c

1
user3638471

HttpUtility.ParseQueryString(Request.Url.Query) return là HttpValueCollection (lớp bên trong). Nó kế thừa từ NameValueCollection.

    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); 
1
alex1kirch

Vì mọi người dường như đang dán giải pháp của anh ấy .. đây là của tôi :-) Tôi cần điều này từ trong thư viện lớp mà không cần System.Web để lấy các tham số id từ các siêu liên kết được lưu trữ.

Tôi muốn chia sẻ vì tôi thấy giải pháp này nhanh hơn và đẹp hơn.

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

Sử dụng:

Statics.QueryGet(url, "id")
1
Tiele Declercq

Nhấn lên Request.QueryString.Keys cho NameValueCollection của tất cả các tham số chuỗi truy vấn.

0
Mark Glorie
        var q = Request.QueryString;
        NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
0
Hamit YILDIRIM

Để nhận tất cả các giá trị Chuỗi truy vấn, hãy thử điều này:

    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
0
mirko cro 1234