URL parametrelerini .NET'te bir dizeden alma


239

Ben aslında bir url. NET bir dize var. Belirli bir parametreden değeri almak için kolay bir yol istiyorum.

Normalde, sadece kullanmak istiyorum Request.Params["theThingIWant"], ama bu dize istekten değil. Ben Uriböyle yeni bir öğe oluşturabilirsiniz :

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);

Ben myUri.Querysorgu dizesi almak için kullanabilirsiniz ... ama sonra görünüşe göre onu bölme bazı regexy yolu bulmak zorunda.

Açık bir şey eksik mi, yoksa böyle bir regex oluşturma bu kısa yapmak için hiçbir yerleşik var mı, vb?

Yanıtlar:


494

Dönen statik sınıf ParseQueryStringyöntemini kullanın .System.Web.HttpUtilityNameValueCollection

Uri myUri = new Uri("http://www.example.com?param1=good&param2=bad");
string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");

Http://msdn.microsoft.com/en-us/library/ms150046.aspx adresindeki belgeleri kontrol edin.


14
Bu ilk parametreyi algılamıyor gibi görünüyor. örneğin " google.com/… " ayrıştırılması q parametresini algılamaz
Andrew Shepherd

@Andrew onayladım. Garip (böcek?). Yine de kullanabilirsiniz HttpUtility.ParseQueryString(myUri.Query).Get(0)ve ilk parametre ayıklayacaktır. ``
Mariusz Pawelski

Parametreli bir sorgu URL'si oluşturmak için herhangi bir .NET aracı?
Shimmy Weitzhandler

6
İle tam sorgu URL'lerini ayrıştıramazsınız HttpUtility.ParseQueryString(string)! Adından da anlaşılacağı gibi, sorgu parametrelerine sahip URL'leri değil, Sorgu Dizelerini ayrıştırmaktır. Bunu yapmak istiyorsanız, önce şu şekilde bölmelisiniz ?: Url.Split('?')ve son elemanı (duruma ve neye ihtiyacınız olduğuna bağlı olarak) [0]veya LINQ'ları Last()/ kullanarak elde etmelisiniz LastOrDefault().
Kosiek

1
Bunu kendim denerken, imza şu şekilde değişmiş gibi görünüyor: HttpUtility.ParseQueryString (uri.Query) .GetValues ​​("param1"). First ()
Senatör

48

Muhtemelen istediğin budur

var uri = new Uri("http://domain.test/Default.aspx?var1=true&var2=test&var3=3");
var query = HttpUtility.ParseQueryString(uri.Query);

var var2 = query.Get("var2");

34

Herhangi bir nedenle, kullanmak istemiyorsanız veya kullanmak istemiyorsanız başka bir alternatif daha HttpUtility.ParseQueryString() .

Bu, "hatalı biçimlendirilmiş" sorgu dizelerine biraz toleranslı olacak şekilde üretilmiştir, yani http://test/test.html?empty=boş bir değere sahip bir parametre haline gelir. Arayan gerekirse parametreleri doğrulayabilir.

public static class UriHelper
{
    public static Dictionary<string, string> DecodeQueryParameters(this Uri uri)
    {
        if (uri == null)
            throw new ArgumentNullException("uri");

        if (uri.Query.Length == 0)
            return new Dictionary<string, string>();

        return uri.Query.TrimStart('?')
                        .Split(new[] { '&', ';' }, StringSplitOptions.RemoveEmptyEntries)
                        .Select(parameter => parameter.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries))
                        .GroupBy(parts => parts[0],
                                 parts => parts.Length > 2 ? string.Join("=", parts, 1, parts.Length - 1) : (parts.Length > 1 ? parts[1] : ""))
                        .ToDictionary(grouping => grouping.Key,
                                      grouping => string.Join(",", grouping));
    }
}

Ölçek

[TestClass]
public class UriHelperTest
{
    [TestMethod]
    public void DecodeQueryParameters()
    {
        DecodeQueryParametersTest("http://test/test.html", new Dictionary<string, string>());
        DecodeQueryParametersTest("http://test/test.html?", new Dictionary<string, string>());
        DecodeQueryParametersTest("http://test/test.html?key=bla/blub.xml", new Dictionary<string, string> { { "key", "bla/blub.xml" } });
        DecodeQueryParametersTest("http://test/test.html?eins=1&zwei=2", new Dictionary<string, string> { { "eins", "1" }, { "zwei", "2" } });
        DecodeQueryParametersTest("http://test/test.html?empty", new Dictionary<string, string> { { "empty", "" } });
        DecodeQueryParametersTest("http://test/test.html?empty=", new Dictionary<string, string> { { "empty", "" } });
        DecodeQueryParametersTest("http://test/test.html?key=1&", new Dictionary<string, string> { { "key", "1" } });
        DecodeQueryParametersTest("http://test/test.html?key=value?&b=c", new Dictionary<string, string> { { "key", "value?" }, { "b", "c" } });
        DecodeQueryParametersTest("http://test/test.html?key=value=what", new Dictionary<string, string> { { "key", "value=what" } });
        DecodeQueryParametersTest("http://www.google.com/search?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22",
            new Dictionary<string, string>
            {
                { "q", "energy+edge" },
                { "rls", "com.microsoft:en-au" },
                { "ie", "UTF-8" },
                { "oe", "UTF-8" },
                { "startIndex", "" },
                { "startPage", "1%22" },
            });
        DecodeQueryParametersTest("http://test/test.html?key=value;key=anotherValue", new Dictionary<string, string> { { "key", "value,anotherValue" } });
    }

    private static void DecodeQueryParametersTest(string uri, Dictionary<string, string> expected)
    {
        Dictionary<string, string> parameters = new Uri(uri).DecodeQueryParameters();
        Assert.AreEqual(expected.Count, parameters.Count, "Wrong parameter count. Uri: {0}", uri);
        foreach (var key in expected.Keys)
        {
            Assert.IsTrue(parameters.ContainsKey(key), "Missing parameter key {0}. Uri: {1}", key, uri);
            Assert.AreEqual(expected[key], parameters[key], "Wrong parameter value for {0}. Uri: {1}", parameters[key], uri);
        }
    }
}

Xamarin projesi için yararlı, HttpUtility kullanılamaz nerede
Artemious

12

@Andrew ve @CZFox

Ben aynı hata vardı ve bu parametre bir aslında olması neden bulundu: http://www.example.com?param1ve param1bir ne beklenir değil.

Soru işaretinden önce ve soru işaretini içeren tüm karakterleri kaldırarak bu sorunu giderir. Dolayısıyla, özünde HttpUtility.ParseQueryStringişlev yalnızca aşağıdaki gibi soru işaretinden sonra yalnızca karakterler içeren geçerli bir sorgu dizesi parametresi gerektirir:

HttpUtility.ParseQueryString ( "param1=good&param2=bad" )

Geçici çözümüm:

string RawUrl = "http://www.example.com?param1=good&param2=bad";
int index = RawUrl.IndexOf ( "?" );
if ( index > 0 )
    RawUrl = RawUrl.Substring ( index ).Remove ( 0, 1 );

Uri myUri = new Uri( RawUrl, UriKind.RelativeOrAbsolute);
string param1 = HttpUtility.ParseQueryString( myUri.Query ).Get( "param1" );`

URI başlatıldığında "Geçersiz URI: URI'nin biçimi belirlenemedi" hatasını alıyorum. Bu çözümün amaçlandığı gibi çalıştığını düşünmüyorum.
Paul Matthews

@ PaulMatthews, haklısın. Bu verilen çözüm sırasında, eski .net framework 2.0 kullanıyordum. Onaylamak için, bu çözümü kopyalayıp Joseph Albahara tarafından LINQPad v2'ye yapıştırdım ve bahsettiğiniz aynı hatayı aldım.
Mo Gauvin

@PaulMatthews, Düzeltmek için Uri myUri = yeni Uri (RawUrl) yazan satırı kaldırın; ve sadece RawUrl'i aşağıdaki gibi son ifadeye iletir: string param1 = HttpUtility.ParseQueryString (RawUrl) .Get ("param2");
Mo Gauvin

Evet, yalnızca sorgu dizesi bölümünü ayrıştırması, adda ve belgelerde bulunur. Bu bir hata değil. Nasıl daha net hale getirebileceklerinden bile emin değilim. ParseQueryStringsorgu dizelerini ayrıştırır.
PandaWood

12

Görünüşe göre değerleri üzerinde döngü myUri.Queryve oradan ayrıştırmak gerekir.

 string desiredValue;
 foreach(string item in myUri.Query.Split('&'))
 {
     string[] parts = item.Replace("?", "").Split('=');
     if(parts[0] == "desiredKey")
     {
         desiredValue = parts[1];
         break;
     }
 }

Ancak, bir grup hatalı biçimlendirilmiş URL'lerde test etmeden kullanmazdım. Bunların bazılarına / hepsine zarar verebilir:

  • hello.html?
  • hello.html?valuelesskey
  • hello.html?key=value=hi
  • hello.html?hi=value?&b=c
  • vb

4

İlk parametreyle de çalışması için aşağıdaki geçici çözümü kullanabilirsiniz:

var param1 =
    HttpUtility.ParseQueryString(url.Substring(
        new []{0, url.IndexOf('?')}.Max()
    )).Get("param1");

2

FillFromStringYöntemini görüntülemek için .NET Reflector kullanın System.Web.HttpValueCollection. Bu, ASP.NET'in Request.QueryStringkoleksiyonu doldurmak için kullandığı kodu verir .


1

Veya URL'yi bilmiyorsanız (sabit kodlamayı önlemek için, AbsoluteUri

Misal ...

        //get the full URL
        Uri myUri = new Uri(Request.Url.AbsoluteUri);
        //get any parameters
        string strStatus = HttpUtility.ParseQueryString(myUri.Query).Get("status");
        string strMsg = HttpUtility.ParseQueryString(myUri.Query).Get("message");
        switch (strStatus.ToUpper())
        {
            case "OK":
                webMessageBox.Show("EMAILS SENT!");
                break;
            case "ER":
                webMessageBox.Show("EMAILS SENT, BUT ... " + strMsg);
                break;
        }

0

QueryString'inizi Varsayılan sayfada almak istiyorsanız Varsayılan sayfa geçerli sayfa URL'niz anlamına gelir. bu kodu deneyebilirsiniz:

string paramIl = HttpUtility.ParseQueryString(this.ClientQueryString).Get("city");

0

Bu aslında çok basit ve bu benim için çalıştı :)

        if (id == "DK")
        {
            string longurl = "selectServer.aspx?country=";
            var uriBuilder = new UriBuilder(longurl);
            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
            query["country"] = "DK";

            uriBuilder.Query = query.ToString();
            longurl = uriBuilder.ToString();
        } 

0

Bir dizeden gelen tüm sorgu dizelerini döngüye almak isteyen herkes için

        foreach (var item in new Uri(urlString).Query.TrimStart('?').Split('&'))
        {
            var subStrings = item.Split('=');

            var key = subStrings[0];
            var value = subStrings[1];

            // do something with values
        }


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.