2012-06-15 8 views
23

Jak usunąć ciąg zapytania z klucza z adresu URL?Jak skutecznie usunąć ciąg kwerendy według klucza z adresu URL?

Mam poniżej metody, która działa dobrze, ale po prostu zastanawiam się, czy istnieje lepszy/krótszy sposób? lub wbudowaną metodą .NET, która może to zrobić bardziej efektywnie?

public static string RemoveQueryStringByKey(string url, string key) 
     { 
      var indexOfQuestionMark = url.IndexOf("?"); 
      if (indexOfQuestionMark == -1) 
      { 
       return url; 
      } 

      var result = url.Substring(0, indexOfQuestionMark); 
      var queryStrings = url.Substring(indexOfQuestionMark + 1); 
      var queryStringParts = queryStrings.Split(new [] {'&'}); 
      var isFirstAdded = false; 

      for (int index = 0; index <queryStringParts.Length; index++) 
      { 
       var keyValue = queryStringParts[index].Split(new char[] { '=' }); 
       if (keyValue[0] == key) 
       { 
        continue; 
       } 

       if (!isFirstAdded) 
       { 
        result += "?"; 
        isFirstAdded = true; 
       } 
       else 
       { 
        result += "&"; 
       } 

       result += queryStringParts[index]; 
      } 

      return result; 
     } 

Na przykład mogę nazwać to lubią:

Console.WriteLine(RemoveQueryStringByKey(@"http://www.domain.com/uk_pa/PostDetail.aspx?hello=hi&xpid=4578", "xpid")); 

Mam nadzieję, że pytanie jest jasne.

Dzięki,

+1

możliwe duplikat [URL kwerendy - Znajdź wymienić, dodawać, zaktualizować wartości?] (http://stackoverflow.com/questions/1163956/url-querystring-find-replace-add-update-values) –

+0

Tag: "reinventing-the-wheel" ["System.Web.HttpUtility.ParseQueryString"] –

+0

nie ma pełnego rozwiązania ani odpowiedzi na zadane pytanie. –

Odpowiedz

60

Działa to dobrze:

public static string RemoveQueryStringByKey(string url, string key) 
     {     
      var uri = new Uri(url); 

      // this gets all the query string key value pairs as a collection 
      var newQueryString = HttpUtility.ParseQueryString(uri.Query); 

      // this removes the key if exists 
      newQueryString.Remove(key); 

      // this gets the page path from root without QueryString 
      string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path); 

      return newQueryString.Count > 0 
       ? String.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString) 
       : pagePathWithoutQueryString; 
     } 

przykład:

RemoveQueryStringByKey("https://www.google.co.uk/search?#hl=en&output=search&sclient=psy-ab&q=cookie", "q"); 

i powraca:

https://www.google.co.uk/#hl=en&output=search&sclient=psy-ab 
+0

+1 sukces przy minimalnym kodowaniu. – Hoque

+1

ciąg nie zawiera definicji dla metody FormatWith – rahularyansharma

+0

Czy można to zrobić bez użycia FormatWith? To nie jest dostępne w .NET 4.0 – NickG

1
var qs = System.Web.HttpUtility.ParseQueryString(queryString); 
var str = qs.Get(key); 

Ta klasa pomocnika również ustawił metod.

+2

To nie jest pełne rozwiązanie. – NickV

1

Jak o tym:

 string RemoveQueryStringByKey(string url, string key) 
    { 
     string ret = string.Empty; 

     int index = url.IndexOf(key); 
     if (index > -1) 
     { 
      string post = string.Empty; 

      // Find end of key's value 
      int endIndex = url.IndexOf('&', index); 
      if (endIndex != -1) // Last query string value? 
      { 
       post = url.Substring(endIndex, url.Length - endIndex); 
      } 

      // Decrement for ? or & character 
      --index; 
      ret = url.Substring(0, index) + post; 
     } 

     return ret; 
    } 
+0

nie działa .... – Ash

1

znalazłem sposób bez użycia wyrażenia regularnego:

private string RemoveQueryStringByKey(string sURL, string sKey) { 
    string sOutput = string.Empty; 

    int iQuestion = sURL.IndexOf('?'); 
    if (iQuestion == -1) return (sURL); 

    int iKey = sURL.Substring(iQuestion).IndexOf(sKey) + iQuestion; 
    if (iKey == -1) return (sURL); 

    int iNextAnd = sURL.Substring(iKey).IndexOf('&') + iKey + 1; 

    if (iNextAnd == -1) { 
     sOutput = sURL.Substring(0, iKey - 1); 
    } 
    else { 
     sOutput = sURL.Remove(iKey, iNextAnd - iKey); 
    } 

    return (sOutput); 
} 

Próbowałem to z dodaniem innego pola na końcu, i to działa dobrze na to zbyt.

+0

nie działa, muszę zacząć tworzyć swój własny kod – Ash

0

myślę najkrótszą drogę (to wierzę produkuje poprawny adres URL w każdym przypadku, zakładając URL było ważne, aby rozpocząć) byłoby użyć tego wyrażenia regularnego (gdzie getRidOf jest nazwa zmiennej próbujesz do usunięcia) i zastąpienie jest ciągiem o zerowej długości ""):

(?<=[?&])getRidOf=[^&]*(&|$) 

a może nawet

\bgetRidOf=[^&]*(&|$) 

natomiast prawdopodobnie nie absolutna pr ettiest URL, myślę wszystkie są ważne:

  INPUT           OUTPUT 
     -----------         ------------ 
blah.com/blah.php?getRidOf=d.co&blah=foo  blah.com/blah.php?blah=foo 
blah.com/blah.php?f=0&getRidOf=d.co&blah=foo blah.com/blah.php?f=0&blah=foo 
blah.com/blah.php?hello=true&getRidOf=d.co  blah.com/blah.php?hello=true& 
blah.com/blah.php?getRidOf=d.co     blah.com/blah.php? 

i jest to proste regex zastąpić:

Dim RegexObj as Regex = New Regex("(?<=[?&])getRidOf=[^&]*(&|$)") 
RegexObj.Replace("source.url.com/find.htm?replace=true&getRidOf=PLEASE!!!", "") 

... powinno skutkować ciąg:

"source.url.com/find.htm?replace=true&" 

... który wydaje się być ważny dla ASP.Aplikacja netto, podczas gdy replace robi równe true (nie true& lub coś podobnego)

postaram się dostosować, jeśli masz przypadek, w którym nie będzie działać :)

0

Poniższy kod przed usunięciem użytkownika QueryString.

PropertyInfo isreadonly = 
      typeof(System.Collections.Specialized.NameValueCollection).GetProperty(
      "IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); 
     // make collection editable 
     isreadonly.SetValue(this.Request.QueryString, false, null); 
     // remove 
     this.Request.QueryString.Remove("yourKey"); 
0
public static string RemoveQueryStringByKey(string sURL, string sKey) 
    { 
     string sOutput = string.Empty; 
     string sToReplace = string.Empty; 

     int iFindTheKey = sURL.IndexOf(sKey); 
     if (iFindTheKey == -1) return (sURL); 

     int iQuestion = sURL.IndexOf('?'); 
     if (iQuestion == -1) return (sURL); 

     string sEverythingBehindQ = sURL.Substring(iQuestion); 
     List<string> everythingBehindQ = new List<string>(sEverythingBehindQ.Split('&')); 
     foreach (string OneParamPair in everythingBehindQ) 
     { 
      int iIsKeyInThisParamPair = OneParamPair.IndexOf(sKey); 
      if (iIsKeyInThisParamPair != -1) 
      { 
       sToReplace = "&" + OneParamPair; 
      } 
     } 

     sOutput = sURL.Replace(sToReplace, ""); 
     return (sOutput); 
    } 
-1
string url = HttpContext.Current.Request.Url.AbsoluteUri; 
string[] separateURL = url.Split('?'); 

NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(separateURL[1]); 
queryString.Remove("param_toremove"); 

string revisedurl = separateURL[0] + "?" + queryString.ToString(); 
+0

Nie przetworzony przypadek, gdy brak zapytania – Pavel

0

Niestety jest to trochę brudny, ale powinien działać w starszym ramach

public String RemoveQueryString(String rawUrl , String keyName) 
{ 
    var currentURL_Split = rawUrl.Split('&').ToList(); 
    currentURL_Split = currentURL_Split.Where(o => !o.ToLower().StartsWith(keyName.ToLower()+"=")).ToList(); 
    String New_RemovedKey = String.Join("&", currentURL_Split.ToArray()); 
    New_RemovedKey = New_RemovedKey.Replace("&&", "&"); 
    return New_RemovedKey; 
} 
0

Oto moje rozwiązanie:

I'v dodane dodatkowe walidacji wejścia.

public static void TryRemoveQueryStringByKey(ref string url, string key) 
{ 
    if (string.IsNullOrEmpty(url) || 
     string.IsNullOrEmpty(key) || 
     Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false) 
    { 
     return false; 
    }    

    try 
    { 
     Uri uri = new Uri(url); 

     // This gets all the query string key value pairs as a collection 
     NameValueCollection queryCollection = HttpUtility.ParseQueryString(uri.Query); 
     string keyValue = queryCollection.Get(key); 

     if (url.IndexOf("&" + key + "=" + keyValue, StringComparison.OrdinalIgnoreCase) >= 0) 
     { 
      url = url.Replace("&" + key + "=" + keyValue, String.Empty); 
      return true; 
     } 
     else if (url.IndexOf("?" + key + "=" + keyValue, StringComparison.OrdinalIgnoreCase) >= 0) 
     { 
      url = url.Replace("?" + key + "=" + keyValue, String.Empty); 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    catch 
    { 
     return false; 
    } 
} 

Niektóre przykłady testowania jednostka:

string url1 = "http://www.gmail.com?a=1&cookie=cookieValue" 
Assert.IsTrue(TryRemoveQueryStringByKey(ref url1,"cookie")); //OUTPUT: "http://www.gmail.com?a=1" 

string url2 = "http://www.gmail.com?cookie=cookieValue" 
Assert.IsTrue(TryRemoveQueryStringByKey(ref url2,"cookie")); //OUTPUT: "http://www.gmail.com" 

string url3 = "http://www.gmail.com?cookie=" 
Assert.IsTrue(TryRemoveQueryStringByKey(ref url2,"cookie")); //OUTPUT: "http://www.gmail.com" 
0

Możemy również zrobić to za pomocą regex

string queryString = "Default.aspx?Agent=10&Language=2"; //Request.QueryString.ToString(); 
string parameterToRemove="Language"; //parameter which we want to remove 
string regex=string.Format("(&{0}=[^&\s]+|{0}=[^&\s]+&?)",parameterToRemove); 
string finalQS = Regex.Replace(queryString, regex, ""); 

https://regexr.com/3i9vj