2012-06-15 11 views
23

Come rimuovere una stringa di query per chiave da un URL?Come rimuovere in modo efficiente una stringa di query per chiave da un URL?

Ho il metodo seguente che funziona bene ma mi chiedo solo se esiste un modo migliore/più breve? o un metodo .NET integrato che può farlo in modo più efficiente?

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

Per esempio posso chiamare le cose come:

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

auguriamo che la questione è chiara.

Grazie,

+1

possibile duplicato di [URL Querystring - Trova, sostituire, aggiungere, aggiornare i valori?] (http://stackoverflow.com/questions/1163956/url-querystring-find-replace-add-update-values) –

+0

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

+0

non ha la soluzione completa né risponde alla domanda posta. –

risposta

60

Questo metodo funziona bene:

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

un esempio:

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

e ritorni:

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

+1 successo con la codifica minima. – Hoque

+1

stringa non contiene la definizione per il metodo FormatWith – rahularyansharma

+0

C'è un modo per farlo senza usare FormatWith? Questo non è disponibile in .NET 4.0 – NickG

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

Questa classe di supporto anche ha stabilito metodi.

+2

Questa non è una soluzione completa. – NickV

1

ne dite di questo:

 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

non funziona .... – Ash

1

ho trovato un modo senza utilizzare Regex:

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

Ho provato questo con l'aggiunta di un altro campo, alla fine, e funziona benissimo anche per questo.

+0

non funziona, ho bisogno di iniziare a creare il mio codice – Ash

0

Sto pensando la via più breve (che io credo produce un URL valido in tutti i casi, assumendo l'URL era valida per cominciare) sarebbe quella di utilizzare questo regex (dove getRidOf è il nome della variabile che si sta cercando per rimuovere) e la sostituzione è una stringa di lunghezza zero ""):

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

o perfino

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

mentre forse non l'assoluto pr ettiest URL, io credo sono tutti validi:

  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? 

ed è una semplice espressione regolare sostituzione:

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

... dovrebbe comportare la stringa:

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

... che sembra essere valido per un ASP.NET applicazione, mentre replace fa uguale true (non true& o qualcosa di simile)

cercherò di adattare se si dispone di un caso in cui non funzionerà :)

0

Sotto il codice prima di eliminare il 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

Caso non elaborato quando nessuna query – Pavel

0

Spiacente, questo è un po 'sporca, ma dovrebbe funzionare nel quadro più vecchio

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

Qui è la mia soluzione:

I'v aggiunto un po' di convalida dell'input in più.

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

Alcuni esempi di unit test:

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

Possiamo anche farlo utilizzando espressioni regolari

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

Problemi correlati