【问题标题】:How to replace url-parameter?如何替换 url 参数?
【发布时间】:2011-07-31 19:57:17
【问题描述】:

给出的 URL 类似于 http://localhost:1973/Services.aspx?idProject=10&idService=14

替换两个 url 参数值(例如 10 到 12 和 14 到 7)最直接的方法是什么?

Regex、String.Replace、Substring 或 LinQ - 我有点卡住了。

提前谢谢你,

提姆


我以以下结束,这对我有用,因为此页面只有这两个参数:

string newUrl = url.Replace(url.Substring(url.IndexOf("Services.aspx?") + "Services.aspx?".Length), string.Format("idProject={0}&idService={1}", Services.IdProject, Services.IdService));

但是谢谢你的建议:)

【问题讨论】:

    标签: c# .net asp.net url string


    【解决方案1】:

    这就是我要做的:

    public static class UrlExtensions
    {
        public static string SetUrlParameter(this string url, string paramName, string value)
        {
            return new Uri(url).SetParameter(paramName, value).ToString();
        }
    
        public static Uri SetParameter(this Uri url, string paramName, string value)
        {           
            var queryParts = HttpUtility.ParseQueryString(url.Query);
            queryParts[paramName] = value;
            return new Uri(url.AbsoluteUriExcludingQuery() + '?' + queryParts.ToString());
        }
    
        public static string AbsoluteUriExcludingQuery(this Uri url)
        {
            return url.AbsoluteUri.Split('?').FirstOrDefault() ?? String.Empty;
        }
    }
    

    用法:

    string oldUrl = "http://localhost:1973/Services.aspx?idProject=10&idService=14";
    string newUrl = oldUrl.SetUrlParameter("idProject", "12").SetUrlParameter("idService", "7");
    

    或者:

    Uri oldUrl = new Uri("http://localhost:1973/Services.aspx?idProject=10&idService=14");
    Uri newUrl = oldUrl.SetParameter("idProject", "12").SetParameter("idService", "7");
    

    【讨论】:

    • 谢谢,看起来很有希望,我稍后再仔细看看。
    【解决方案2】:

    这是我的实现:

    using System;
    using System.Collections.Specialized;
    using System.Web; // For this you need to reference System.Web assembly from the GAC
    
    public static class UriExtensions
    {
        public static Uri SetQueryVal(this Uri uri, string name, object value)
        {
            NameValueCollection nvc = HttpUtility.ParseQueryString(uri.Query);
            nvc[name] = (value ?? "").ToString();
            return new UriBuilder(uri) {Query = nvc.ToString()}.Uri;
        }
    }
    

    这里有一些例子:

    new Uri("http://host.com/path").SetQueryVal("par", "val")
    // http://host.com/path?par=val
    
    new Uri("http://host.com/path?other=val").SetQueryVal("par", "val")
    // http://host.com/path?other=val&par=val
    
    new Uri("http://host.com/path?PAR=old").SetQueryVal("par", "new")
    // http://host.com/path?PAR=new
    
    new Uri("http://host.com/path").SetQueryVal("par", "/")
    // http://host.com/path?par=%2f
    
    new Uri("http://host.com/path")
        .SetQueryVal("p1", "v1")
        .SetQueryVal("p2", "v2")
    // http://host.com/path?p1=v1&p2=v2
    

    【讨论】:

    • 美观无副作用
    【解决方案3】:

    C# HttpUtility.ParseQueryString 实用程序将为您完成繁重的工作。您将希望在最终版本中进行一些更强大的 null 检查。

        // Let the object fill itself 
        // with the parameters of the current page.
        var qs = System.Web.HttpUtility.ParseQueryString(Request.RawUrl);
    
        // Read a parameter from the QueryString object.
        string value1 = qs["name1"];
    
        // Write a value into the QueryString object.
        qs["name1"] = "This is a value";
    

    【讨论】:

    • 为什么要将 RawUrl 传递给 ParseQueryString?查询字符串和 URL 是有区别的。您不应该先拆分 URL 以提取查询字符串吗?
    • 是的,很好的答案,但是如果您传递整个 URL,那么您的第一个参数的键将看起来像 http://localhost:50819/Request?pagenumber 而不仅仅是 pagenumber
    【解决方案4】:

    我在一个旧代码示例中发现了这一点,不需要太多改进,采用IEnumerable<KeyValuePair<string,object>> 可能比当前的分隔字符串更好。

        public static string AppendQuerystring( string keyvalue)
        {
            return AppendQuerystring(System.Web.HttpContext.Current.Request.RawUrl, keyvalue);
        }
        public static string AppendQuerystring(string url, string keyvalue)
        {
            string dummyHost = "http://www.test.com:80/";
            if (!url.ToLower().StartsWith("http"))
            {
                url = String.Concat(dummyHost, url);
            }
            UriBuilder builder = new UriBuilder(url);
            string query = builder.Query;
            var qs = HttpUtility.ParseQueryString(query);
            string[] pts = keyvalue.Split('&');
            foreach (string p in pts)
            {
                string[] pts2 = p.Split('=');
                qs.Set(pts2[0], pts2[1]);
            }
            StringBuilder sb = new StringBuilder();
    
            foreach (string key in qs.Keys)
            {
                sb.Append(String.Format("{0}={1}&", key, qs[key]));
            }
            builder.Query = sb.ToString().TrimEnd('&');
            string ret = builder.ToString().Replace(dummyHost,String.Empty);
            return ret;
        }
    

    用法

       var url = AppendQueryString("http://localhost:1973/Services.aspx?idProject=10&idService=14","idProject=12&idService=17");
    

    【讨论】:

    • 谢谢。我使用了一个简单的替换,因为页面只有这两个参数,但你的答案是一个更好的例子;)
    • 您应该声明键值应该正确地进行 uri 编码,这样才能正常工作。如果我想用这个发送query=?est,它将创建一个无效的查询字符串
    【解决方案5】:

    最直接的方法是String.Replace,但如果你的uri看起来像http://localhost:1212/base.axd?id=12&otherId=12,你最终会遇到问题

    【讨论】:

    • 通过简单的字符串替换无法正确满足 OP 的要求。
    • 我知道,因此我声明(尽管含蓄地)最直接的方法(按要求)不是正确的方法。
    • 实际上我以使用 String.Replace 结束(见我的编辑),它符合我的要求。
    • @Tim - 如果这是您当时最喜欢的答案,我至少可以得到一个支持吗?
    【解决方案6】:

    我最近发布了UriBuilderExtended,这是一个库,可以通过扩展方法轻松编辑UriBuilder 对象上的查询字符串。

    您基本上只需在构造函数中使用当前 URL 字符串创建一个 UriBuilder 对象,通过扩展方法修改查询,然后从 UriBuilder 对象构建新的 URL 字符串。

    快速示例:

    string myUrl = "http://www.example.com/?idProject=10&idService=14";
    
    UriBuilder builder = new UriBuilder(myUrl);
    
    builder.SetQuery("idProject", "12");
    builder.SetQuery("idService", "7");
    
    string newUrl = builder.Url.ToString();
    

    URL 字符串是从 builder.Uri.ToString() 获取的,而不是从 builder.ToString() 获取的,因为它有时呈现的结果与您的预期不同。

    您可以通过NuGet获取图书馆。

    更多示例here

    欢迎评论和祝福。

    【讨论】:

      【解决方案7】:

      最可靠的方法是使用 Uri 类来解析字符串,更改参数值,然后构建结果。

      URL 的工作方式有许多细微差别,虽然您可以尝试使用自己的正则表达式来执行此操作,但处理所有情况很快就会变得复杂。

      所有其他方法都会在子字符串匹配等方面出现问题,我什至看不到 Linq 在这里是如何应用的。

      【讨论】:

        【解决方案8】:

        我有同样的问题,我用从这里的评论中得到的以下三行代码解决了这个问题(如 Stephen Oberauer 的解决方案,但没有过度设计):

            ' EXAMPLE: 
            '    INPUT:  /MyUrl.aspx?IdCat=5&Page=3
            '    OUTPUT: /MyUrl.aspx?IdCat=5&Page=4
            ' Get the URL and breaks each param into Key/value collection: 
            Dim Col As NameValueCollection = System.Web.HttpUtility.ParseQueryString(Request.RawUrl)
        
            ' Changes the param you want in the url, with the value you want
            Col.Item("Page") = "4"
        
            ' Generates the output string with the result (it also includes the name of the page, not only the params )
            Dim ChangedURL As String = HttpUtility.UrlDecode(Col.ToString())
        

        这是使用 VB .NET 的解决方案,但转换为 C# 非常简单。

        【讨论】:

          猜你喜欢
          • 2011-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-18
          • 2018-01-17
          • 1970-01-01
          • 2018-12-01
          相关资源
          最近更新 更多