How to replace url-parameter?

2020-03-18 03:56发布

问题:

given is an URL like http://localhost:1973/Services.aspx?idProject=10&idService=14.

What is the most straightforward way to replace both url-parameter values(for example 10 to 12 and 14 to 7)?

Regex, String.Replace, Substring or LinQ - i'm a little stuck.

Thank you in advance,

Tim


I ended with following, that's working for me because this page has only these two parameter:

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

But thank you for your suggestions :)

回答1:

I found this in an old code example, wouldnt take much to improve it, taking a IEnumerable<KeyValuePair<string,object>> may be better than the current delimeted string.

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

Usage

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


回答2:

This is what I would do:

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

Usage:

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

Or:

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


回答3:

the C# HttpUtility.ParseQueryString utility will do the heavy lifting for you. You will want to do some more robust null checking in your final version.

    // 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";


回答4:

Here is my implementation:

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

and here are some examples:

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


回答5:

The most straightforward way is String.Replace, but you'll end up with problems if your uri looks like http://localhost:1212/base.axd?id=12&otherId=12



回答6:

I have recently released UriBuilderExtended, which is a library that makes editing of query strings on UriBuilder objects a breeze through extension methods.

You basically just create a UriBuilder object with your current URL string in the constructor, modify the query through the extension methods, and build the new URL string from the UriBuilder object.

Quick example:

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 string is obtained from builder.Uri.ToString(), not builder.ToString() as it sometimes renders differently to what you'd expect.

You can get the Library through NuGet.

More examples here.

Comments and wishes are most welcome.



回答7:

The most robust way would be to use the Uri class to parse the string, change te param values and then build the result.

There are many nuances to how URLs work and while you could try to roll your own regex to do this it could quickly get complicate handling all the cases.

All the other methods would have issues with substring matches etc and I don't even see how Linq applies here.



回答8:

I have the same problem and i solved it with the following three lines of code that i get from the coments here (like Stephen Oberauer's solution, but less overenginieered):

    ' 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())

This is the solution using VB .NET but the conversion to C# is strightforward.