C# 如何有效地从Url中按键删除查询字符串?

C# 如何有效地从Url中按键删除查询字符串?,c#,.net,regex,url,query-string,C#,.net,Regex,Url,Query String,如何按键从Url中删除查询字符串 我有下面的方法,效果很好,但只是想知道有没有更好/更短的方法?或者是一个内置的.NET方法,它可以更有效地完成这项工作 public static string RemoveQueryStringByKey(string url, string key) { var indexOfQuestionMark = url.IndexOf("?"); if (indexOfQuestionMark ==

如何按键从Url中删除查询字符串

我有下面的方法,效果很好,但只是想知道有没有更好/更短的方法?或者是一个内置的.NET方法,它可以更有效地完成这项工作

 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;
        }
希望问题清楚

谢谢

    var queryString = "hello=hi&xpid=4578";
    var qs = System.Web.HttpUtility.ParseQueryString(queryString);
    qs.Remove("xpid");
    var newQuerystring = qs.ToString();
这在.NET 5中仍然有效。

这个怎么样:

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

我找到了一种不用正则表达式的方法:

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

我确实尝试过在末尾添加另一个字段,而且效果也不错。

我认为最短的方法(我相信在所有情况下都会生成有效的URL,假设URL一开始是有效的)是使用这个正则表达式(其中
getRidOf
是您试图删除的变量名)替换为零长度字符串
):

虽然可能不是绝对最漂亮的URL,但我认为它们都是有效的:

         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?
这是一个简单的正则表达式替换:

Dim RegexObj as Regex = New Regex("(?<=[?&])getRidOf=[^&]*(&|$)")
RegexObj.Replace("source.url.com/find.htm?replace=true&getRidOf=PLEASE!!!", "")
…这似乎对ASP.Net应用程序有效,而
replace
等于
true
(不是
true&
或类似的内容)

如果您遇到无法使用的情况,我将尝试调整它:)

这很有效:

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;
}
例如:

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

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

在删除
查询字符串之前,请在下面输入代码

 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");
publicstaticstringremoveQueryStringByKey(stringsurl,stringskey)
{
string sOutput=string.Empty;
string sToReplace=string.Empty;
int-iFindTheKey=sURL.IndexOf(sKey);
如果(iFindTheKey==-1)返回(sURL);
intiquestion=sURL.IndexOf(‘?’);
如果(iQuestion==-1)返回(sURL);
字符串sEverythingBehindQ=sURL.Substring(iQuestion);
List everythingBehindQ=新列表(sEverythingBehindQ.Split(“&”);
foreach(everythingBehindQ中的字符串OneParamPair)
{
int iIsKeyInThisParamPair=OneParamPair.IndexOf(sKey);
如果(iIsKeyInThisParamPair!=-1)
{
sToReplace=“&”+OneParamPair;
}
}
sOutput=表面替换(存储位置“”);
返回(sOutput);
}

很抱歉,这有点脏,但应该在旧的框架中工作

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;
}
以下是我的解决方案:

我添加了一些额外的输入验证

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;
    }
}
一些单元测试示例:

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"

我们也可以使用正则表达式来实现

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);   //this will not work for javascript, for javascript you can do following
string finalQS = Regex.Replace(queryString, regex, "");

//javascript(following is not js syntex, just want to give idea how we can able do it in js)
string regex1 = string.Format("(&{0}=[^&\s]+)",parameterToRemove);
string regex2 = string.Format("(\?{0}=[^&\s]+&?)",parameterToRemove);
string finalQS = Regex.Replace(queryString, regex1, "").Replace(queryString, regex2, "");
string queryString=“Default.aspx?Agent=10&Language=2”//Request.QueryString.ToString();
字符串参数toremove=“Language”//要删除的参数

string regex=string.Format(“(&{0}=[^&\s]+|)(?在系统名称空间中调用了一个有用的类。我们可以将它与几个扩展方法一起使用来执行以下操作:

Uri u = new Uri("http://example.com?key1=value1&key2=value2");
u = u.DropQueryItem("key1");
或者像这样:

Uri u = new Uri("http://example.com?key1=value1&key2=value2");
UriBuilder b = new UriBuilder(u);
b.RemoveQueryItem("key1");
u = b.Uri;
扩展方法:

using System;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;

public static class UriExtensions
{
    public static Uri DropQueryItem(this Uri u, string key)
    {
        UriBuilder b = new UriBuilder(u);
        b.RemoveQueryItem(key);
        return b.Uri;
    }
}
public static class UriBuilderExtensions
{
    private static string _ParseQueryPattern = @"(?<key>[^&=]+)={0,1}(?<value>[^&]*)";
    private static Regex _ParseQueryRegex = null;

    private static Regex ParseQueryRegex
    {
        get
        {
            if (_ParseQueryRegex == null)
            {
                _ParseQueryRegex = new Regex(_ParseQueryPattern, RegexOptions.Compiled | RegexOptions.Singleline);
            }
            return _ParseQueryRegex;

        }
    }

    public static void SetQueryItem(this UriBuilder b, string key, string value)
    {
        NameValueCollection parms = ParseQueryString(b.Query);
        parms[key] = value;
        b.Query = RenderQuery(parms);
    }

    public static void RemoveQueryItem(this UriBuilder b, string key)
    {
        NameValueCollection parms = ParseQueryString(b.Query);
        parms.Remove(key);
        b.Query = RenderQuery(parms);
    }       
    private static string RenderQuery(NameValueCollection parms)
    {
        StringBuilder sb = new StringBuilder();
        for (int i=0; i<parms.Count; i++)
        {
            string key = parms.Keys[i];
            sb.Append(key + "=" + parms[key]);
            if (i < parms.Count - 1)
            {
                sb.Append("&");
            }
        }
        return sb.ToString();
    }
    public static NameValueCollection ParseQueryString(string query, bool caseSensitive = true)
    {
        NameValueCollection pairs = new NameValueCollection(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);

        string q = query.Trim().TrimStart(new char[] {'?'});
        MatchCollection matches = ParseQueryRegex.Matches(q);

        foreach (Match m in matches)
        {
            string key = m.Groups["key"].Value;
            string value = m.Groups["value"].Value;
            if (pairs[key] != null)
            {
                pairs[key] = pairs[key] + "," + value;
            }
            else
            {
                pairs[key] = value;
            }

        }

        return pairs;

    }

}
使用系统;
使用System.Collections.Specialized;
使用系统文本;
使用System.Text.RegularExpressions;
公共静态类扩展
{
公共静态Uri DropQueryItem(此Uri u,字符串键)
{
UriBuilder b=新的UriBuilder(u);
b、 RemoveQueryItem(键);
返回b.Uri;
}
}
公共静态类UriBuilderExtensions
{
私有静态字符串_ParseQueryPattern=@“(?[^&=]+)={0,1}(?[^&]*)”;
私有静态正则表达式_ParseQueryRegex=null;
私有静态正则表达式ParseQueryRegex
{
得到
{
if(_ParseQueryRegex==null)
{
_ParseQueryRegex=新正则表达式(_ParseQueryPattern,RegexOptions.Compiled | RegexOptions.Singleline);
}
返回_ParseQueryRegex;
}
}
公共静态void SetQueryItem(此UriBuilder b,字符串键,字符串值)
{
NameValueCollection parms=ParseQueryString(b.Query);
parms[key]=值;
b、 Query=RenderQuery(parms);
}
公共静态void RemoveQueryItem(此UriBuilder b,字符串键)
{
NameValueCollection parms=ParseQueryString(b.Query);
parms.Remove(键);
b、 Query=RenderQuery(parms);
}       
私有静态字符串RenderQuery(NameValueCollection参数)
{
StringBuilder sb=新的StringBuilder();

对于(int i=0;i,这里有一个完整的解决方案,可以使用>=0指定的参数和任何形式的URL:

    /// <summary>
    /// Given a URL in any format, return URL with specified query string param removed if it exists
    /// </summary>
    public static string StripQueryStringParam(string url, string paramToRemove)
    {
        return StripQueryStringParams(url, new List<string> {paramToRemove});
    }

    /// <summary>
    /// Given a URL in any format, return URL with specified query string params removed if it exists
    /// </summary>
    public static string StripQueryStringParams(string url, List<string> paramsToRemove)
    {
        if (paramsToRemove == null || !paramsToRemove.Any()) return url;

        var splitUrl = url.Split('?');
        if (splitUrl.Length == 1) return url;

        var urlFirstPart = splitUrl[0];
        var urlSecondPart = splitUrl[1];

        // Even though in most cases # isn't available to context,
        // we may be passing it in explicitly for helper urls
        var secondPartSplit = urlSecondPart.Split('#');
        var querystring = secondPartSplit[0];
        var hashUrlPart = string.Empty;
        if (secondPartSplit.Length > 1)
        {
            hashUrlPart = "#" + secondPartSplit[1];
        }
        var nvc = HttpUtility.ParseQueryString(querystring);
        if (!nvc.HasKeys()) return url;

        // Remove any matches
        foreach (var key in nvc.AllKeys)
        {
            if (paramsToRemove.Contains(key))
            {
                nvc.Remove(key);
            }
        }

        if (!nvc.HasKeys()) return urlFirstPart;
        return urlFirstPart + 
               "?" + string.Join("&", nvc.AllKeys.Select(c => c.ToString() + "=" + nvc[c.ToString()])) + 
               hashUrlPart;
    }
//
///给定任何格式的URL,如果存在,则返回URL并删除指定的查询字符串param
/// 
公共静态字符串StripQueryStringParam(字符串url,字符串参数删除)
{
返回StripQueryStringParams(url,新列表{paramToRemove});
}
/// 
///给定任意格式的URL,返回URL,如果存在,则删除指定的查询字符串参数
/// 
公共静态字符串StripQueryStringParams(字符串url、列表参数StoreMove)
{
if(paramsToRemove==null | |!paramsToRemove.Any())返回url;
var splitUrl=url.Split(“?”);
如果(splitUrl.Length==1)返回url;
var urlFirstPart=splitUrl[0];
var urlSecondPart=splitUrl[1];
//尽管在大多数情况下#不适用于上下文,
//我们可能会将其显式地传递给帮助器URL
var secondPartSplit=urlsecondapart.Split(“#”);
var querystring=secondPartSplit[0];
var hashUrlPart=string.Empty;
如果(secondPartSplit.Length>1)
{
hashUrlPart=“#”+secondPartSplit[1];
}
var nvc=HttpUtility.ParseQueryString(querystring);
如果(!nvc.HasKeys())返回url;
//删除任何匹配项
foreach(nvc.AllKeys中的变量键)
{
if(paramsToRemove.Contains(键))
{
移除(钥匙);
}
}
如果(!nvc.HasKeys())返回urlFirstPart;
返回urlFirstPart+
“?”+string.Join(“&”,nvc.AllKeys.Select(c=>c.ToString()+”=“+nvc[c.ToString()]))+
哈什尔部分;
}

这个老问题的更现代的答案,以防其他人像我一样偶然发现它

这是使用uric
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"
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);   //this will not work for javascript, for javascript you can do following
string finalQS = Regex.Replace(queryString, regex, "");

//javascript(following is not js syntex, just want to give idea how we can able do it in js)
string regex1 = string.Format("(&{0}=[^&\s]+)",parameterToRemove);
string regex2 = string.Format("(\?{0}=[^&\s]+&?)",parameterToRemove);
string finalQS = Regex.Replace(queryString, regex1, "").Replace(queryString, regex2, "");
Uri u = new Uri("http://example.com?key1=value1&key2=value2");
u = u.DropQueryItem("key1");
Uri u = new Uri("http://example.com?key1=value1&key2=value2");
UriBuilder b = new UriBuilder(u);
b.RemoveQueryItem("key1");
u = b.Uri;
using System;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;

public static class UriExtensions
{
    public static Uri DropQueryItem(this Uri u, string key)
    {
        UriBuilder b = new UriBuilder(u);
        b.RemoveQueryItem(key);
        return b.Uri;
    }
}
public static class UriBuilderExtensions
{
    private static string _ParseQueryPattern = @"(?<key>[^&=]+)={0,1}(?<value>[^&]*)";
    private static Regex _ParseQueryRegex = null;

    private static Regex ParseQueryRegex
    {
        get
        {
            if (_ParseQueryRegex == null)
            {
                _ParseQueryRegex = new Regex(_ParseQueryPattern, RegexOptions.Compiled | RegexOptions.Singleline);
            }
            return _ParseQueryRegex;

        }
    }

    public static void SetQueryItem(this UriBuilder b, string key, string value)
    {
        NameValueCollection parms = ParseQueryString(b.Query);
        parms[key] = value;
        b.Query = RenderQuery(parms);
    }

    public static void RemoveQueryItem(this UriBuilder b, string key)
    {
        NameValueCollection parms = ParseQueryString(b.Query);
        parms.Remove(key);
        b.Query = RenderQuery(parms);
    }       
    private static string RenderQuery(NameValueCollection parms)
    {
        StringBuilder sb = new StringBuilder();
        for (int i=0; i<parms.Count; i++)
        {
            string key = parms.Keys[i];
            sb.Append(key + "=" + parms[key]);
            if (i < parms.Count - 1)
            {
                sb.Append("&");
            }
        }
        return sb.ToString();
    }
    public static NameValueCollection ParseQueryString(string query, bool caseSensitive = true)
    {
        NameValueCollection pairs = new NameValueCollection(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);

        string q = query.Trim().TrimStart(new char[] {'?'});
        MatchCollection matches = ParseQueryRegex.Matches(q);

        foreach (Match m in matches)
        {
            string key = m.Groups["key"].Value;
            string value = m.Groups["value"].Value;
            if (pairs[key] != null)
            {
                pairs[key] = pairs[key] + "," + value;
            }
            else
            {
                pairs[key] = value;
            }

        }

        return pairs;

    }

}
    /// <summary>
    /// Given a URL in any format, return URL with specified query string param removed if it exists
    /// </summary>
    public static string StripQueryStringParam(string url, string paramToRemove)
    {
        return StripQueryStringParams(url, new List<string> {paramToRemove});
    }

    /// <summary>
    /// Given a URL in any format, return URL with specified query string params removed if it exists
    /// </summary>
    public static string StripQueryStringParams(string url, List<string> paramsToRemove)
    {
        if (paramsToRemove == null || !paramsToRemove.Any()) return url;

        var splitUrl = url.Split('?');
        if (splitUrl.Length == 1) return url;

        var urlFirstPart = splitUrl[0];
        var urlSecondPart = splitUrl[1];

        // Even though in most cases # isn't available to context,
        // we may be passing it in explicitly for helper urls
        var secondPartSplit = urlSecondPart.Split('#');
        var querystring = secondPartSplit[0];
        var hashUrlPart = string.Empty;
        if (secondPartSplit.Length > 1)
        {
            hashUrlPart = "#" + secondPartSplit[1];
        }
        var nvc = HttpUtility.ParseQueryString(querystring);
        if (!nvc.HasKeys()) return url;

        // Remove any matches
        foreach (var key in nvc.AllKeys)
        {
            if (paramsToRemove.Contains(key))
            {
                nvc.Remove(key);
            }
        }

        if (!nvc.HasKeys()) return urlFirstPart;
        return urlFirstPart + 
               "?" + string.Join("&", nvc.AllKeys.Select(c => c.ToString() + "=" + nvc[c.ToString()])) + 
               hashUrlPart;
    }
public static string RemoveQueryStringByKey(string url, string key)
{
    var uri = new Uri(url, UriKind.Absolute);
    var queryParts = uri.Query
        .TrimStart('?')
        .Split('&')
        .Where(item => string.CompareOrdinal(item, key) != 0);
    return uri.Scheme + Uri.SchemeDelimiter
        + uri.Authority
        + uri.AbsolutePath
        + "?" + string.Join("&", queryParts);
}
public Uri GetUriWithoutQueryParam( Uri originalUri, string paramKey ) {
  NameValueCollection newQuery = HttpUtility.ParseQueryString( originalUri.Query );
  newQuery.Remove( paramKey );
  return new UriBuilder( originalUri ) { Query = newQuery.ToString() }.Uri;
}