كيفية تحليل سلسلة استعلام في NameValueCollection في .صافي

StackOverflow https://stackoverflow.com/questions/68624

  •  09-06-2019
  •  | 
  •  

سؤال

أود أن تحليل سلسلة مثل p1=6&p2=7&p3=8 في NameValueCollection.

ما هي الطريقة الأكثر أناقة من فعل هذا عندما لم يكن لديك الوصول إلى Page.Request الكائن ؟

هل كانت مفيدة؟

المحلول

هناك المدمج في .صافي فائدة هذه: هتبوتيليتي.ParseQueryString

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

قد تحتاج إلى استبدال querystring مع new Uri(fullUrl).Query.

نصائح أخرى

هتبوتيليتي.ParseQueryString العمل طالما كنت في التطبيق على شبكة الإنترنت أو لا تمانع بما في ذلك الاعتماد على النظام.ويب.طريقة أخرى للقيام بذلك هو:

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

الكثير من الإجابات توفير مخصص أمثلة بسبب قبول الإجابة الاعتماد على النظام.ويب.من مايكروسوفت.AspNet.WebApi.العميل حزمة NuGet هناك UriExtensions.ParseQueryString, أو الطريقة التي يمكن أن تستخدم أيضا:

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

حتى إذا كنت ترغب في تجنب النظام.ويب التبعية و لا أريد أن لفة الخاص بك, هذا هو خيار جيد.

أردت إزالة الاعتماد على النظام.ويب حتى أتمكن من تحليل سلسلة الاستعلام من نشر ClickOnce ، في حين وجود الشروط تقتصر على "عميل فقط إطار فرعية".

أحببت rp الجواب.أضفت بعض منطق إضافية.

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

أنا في حاجة إلى وظيفة أكثر تنوعا مما تم تقديمه بالفعل عند العمل مع OLSC الاستعلامات.

  • القيم قد تحتوي على عدة علامات المساواة
  • فك ترميز الأحرف في كل اسم و قيمة
  • قادرة على تشغيل على العميل إطار
  • قادرة على تشغيل على الهاتف المحمول الإطار.

هنا الحل:

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

قد لا تكون فكرة سيئة أن تك <Extension()> على ذلك أيضا لإضافة القدرة على Uri نفسها.

للقيام بذلك دون System.Web, دون كتابة ذلك بنفسك بدون مزيد من الحزم NuGet:

  1. إضافة مرجع إلى System.Net.Http.Formatting
  2. إضافة using System.Net.Http;
  3. استخدم هذا الكود:

    new Uri(uri).ParseQueryString()
    

https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=مقابل 118).aspx

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

أنا فقط أدركت أن API ويب العميل لديه ParseQueryString طريقة التمديد الذي يعمل على Uri وإرجاع HttpValueCollection:

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

إذا كنت ترغب في تجنب الاعتماد على النظام.ويب المطلوبة لاستخدام هتبوتيليتي.ParseQueryString, هل يمكن استخدام Uri طريقة التمديد ParseQueryString وجدت في System.Net.Http.

تأكد من إضافة إشارة (إذا كنت لم تقم بذلك بالفعل) إلى System.Net.Http في المشروع الخاص بك.

لاحظ أن لديك لتحويل استجابة الجسم صالح Uri بحيث ParseQueryString (في System.Net.Http)يعمل.

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

مجرد وصول الطلب.QueryString.AllKeys ذكر جواب آخر فقط يحصل لك مجموعة من المفاتيح.

HttpUtility.ParseQueryString(Request.Url.Query) العودة HttpValueCollection (الطبقة الداخلية).فإنه يرث من 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); 

إذا كنت لا تريد النظام.ويب الاعتماد فقط لصق هذه التعليمات البرمجية المصدر من هتبوتيليتي الدرجة.

أنا فقط جلد هذا معا من التعليمات البرمجية المصدر مونو.أنه يحتوي على هتبوتيليتي وكل ما تبعيات (مثل IHtmlString, المساعدين, HttpEncoder, HttpQSCollection).

ثم استخدام HttpUtility.ParseQueryString.

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

حيث يبدو أن الجميع لصق له حل..هنا لي :-) أنا في حاجة هذا من داخل مكتبة فئة دون System.Web جلب هوية المعلمات من تخزين الارتباطات التشعبية.

فكرت في مشاركة لأنني أجد هذا الحل أسرع و تبحث على نحو أفضل.

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

الاستخدام:

Statics.QueryGet(url, "id")

ضرب الطلب.QueryString.مفاتيح NameValueCollection من جميع معلمات سلسلة الاستعلام.

الحصول على جميع Querystring القيم جرب هذا:

    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
        var q = Request.QueryString;
        NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());

كنت تترجم إلى C# نسخة من جوش-البني في VB

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

هذا هو قانون بلدي ، أعتقد انها مفيدة جدا:

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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top