1

I don't have the Request, I only have a url string. Also, the url can either be relative or absolute. And since Uri and UriBuilder do not support relative urls, I'll probably have to do it manually, unless there is a trick I'm not aware of. This method will be used in probably more than a thousand lines of code in my project that's why I'd like to do it right.

The following code will break if a relative url is passed:

public static string AddQueryStringIfNotExists(string url, string parameter, string value)
{
    var uriBuilder = new UriBuilder(url);
    var query = HttpUtility.ParseQueryString(uriBuilder.Query);
    if (query[parameter] == null)
    {
        query[parameter] = value;
        uriBuilder.Query = query.ToString();
    }
    return uriBuilder.ToString();
}

P.S. I'm fine with doing it manually by checking whether my parameter appears after the first ? but that would require tackling several edge cases, the thing I'm trying to avoid (like a parameter name contained in another parameter)

2 Answers 2

2

Just check that your url is absolute. If it's not convert it to an absolute url.

Then use HttpUtility.ParseQueryString to parse the query string and add your parameter if needed.

Convert the UriBuilder back into a Uri.

If the input was an absolute Uri return the entire Uri. If the input was relative then return the relative uri.

private static Uri dummy = new Uri("http://dummy/");
public static string AddQueryStringIfNotExists(string url, string parameter, string value)
{
    var uri = new Uri(url, UriKind.RelativeOrAbsolute);
    var uriBuilder = uri.IsAbsoluteUri ? new UriBuilder(url) : new UriBuilder(new Uri(dummy, url));

    var query = HttpUtility.ParseQueryString(uriBuilder.Query);
    if (query[parameter] == null)
    {
        query[parameter] = value;
        uriBuilder.Query = query.ToString();
    }
    return uri.IsAbsoluteUri ? uriBuilder.ToString() : dummy.MakeRelativeUri(new Uri(uriBuilder.ToString())).ToString();
}

Example:

string s = AddQueryStringIfNotExists("somedirectory/mypage/html?something=1", "somethingelse", "1");

Output:

somedirectory/mypage/html?something=1&somethingelse=1

Sign up to request clarification or add additional context in comments.

Comments

1

There can be a simple helper which will transform relative URL to absolute:

public static string ToAbsoluteUrl(this string url, string domain)
{
    var result = url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? url : domain + url;
    return result;
}

url = "/page?skip=0";
url = url.ToAbsoluteUrl("https://example.com"); // https://example.com/page?skip=0
var uriBuilder = new UriBuilder(url);

2 Comments

I wanted to avoid the absolute url because I'll eventually use the output in Response.Redirect which automatically deals with relative URLs. Besides, I'll have to selectively pass the domain every time I have a relative URL which requires a full scan of my project.
If it comes in relative, then convert it to absolute, append your query and then return the relative part of the url. Otherwise handle it the way you are.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.