55

I would like to take the original URL, truncate the query string parameters, and return a cleaned up version of the URL. I would like it to occur across the whole application, so performing through the global.asax would be ideal. Also, I think a 301 redirect would be in order as well.

ie.

in: www.website.com/default.aspx?utm_source=twitter&utm_medium=social-media

out: www.website.com/default.aspx

What would be the best way to achieve this?

Chris
  • 621
  • 1
  • 5
  • 7

7 Answers7

121

System.Uri is your friend here. This has many helpful utilities on it, but the one you want is GetLeftPart:

 string url = "http://www.website.com/default.aspx?utm_source=twitter&utm_medium=social-media";
 Uri uri = new Uri(url);
 Console.WriteLine(uri.GetLeftPart(UriPartial.Path));

This gives the output: http://www.website.com/default.aspx

[The Uri class does require the protocol, http://, to be specified]

GetLeftPart basicallys says "get the left part of the uri up to and including the part I specify". This can be Scheme (just the http:// bit), Authority (the www.website.com part), Path (the /default.aspx) or Query (the querystring).

Assuming you are on an aspx web page, you can then use Response.Redirect(newUrl) to redirect the caller.

starball
  • 20,030
  • 7
  • 43
  • 238
Rob Levine
  • 40,328
  • 13
  • 85
  • 111
  • This what we finally came up with: //begin poor formatting string rawUrl = String.Concat(this.GetApplicationUrl(), Request.RawUrl); if (rawUrl.Contains("/post/")) { bool hasQueryStrings = Request.QueryString.Keys.Count > 1; if (hasQueryStrings) { Uri uri = new Uri(rawUrl); rawUrl = uri.GetLeftPart(UriPartial.Path); HtmlLink canonical = new HtmlLink(); canonical.Href = rawUrl; canonical.Attributes["rel"] = "canonical"; Page.Header.Controls.Add(canonical); } } Followed by a function to properly fetch the application URL. Works perfectly. – Chris Jul 28 '09 at 04:13
  • @Rob Levine: [`Uri.GetLeftPart`](https://learn.microsoft.com/en-us/dotnet/api/system.uri.getleftpart) actually will get the left part of the URL _containing_ (i.e. _up through_) the specified part. If it only got _up to_ the specified part, it would stop just short of the whole part you wanted. – Suncat2000 Mar 18 '21 at 13:58
  • 1
    @Suncat2000 - now clarified in the text above - thanks – Rob Levine Mar 18 '21 at 21:42
8

Here is a simple trick

Dim uri = New Uri(Request.Url.AbsoluteUri)

dim reqURL = uri.GetLeftPart(UriPartial.Path)
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Farooq Kaiser
  • 339
  • 4
  • 5
2

Here is a quick way of getting the root path sans the full path and query.

string path = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery,"");
calmcajun
  • 173
  • 1
  • 4
  • 17
1

This may look a little better.

    string rawUrl = String.Concat(this.GetApplicationUrl(), Request.RawUrl);

    if (rawUrl.Contains("/post/"))
    {
        bool hasQueryStrings = Request.QueryString.Keys.Count > 1;

        if (hasQueryStrings)
        {
            Uri uri = new Uri(rawUrl);
            rawUrl = uri.GetLeftPart(UriPartial.Path);

            HtmlLink canonical = new HtmlLink();
            canonical.Href = rawUrl;
            canonical.Attributes["rel"] = "canonical";
            Page.Header.Controls.Add(canonical);
        }
    }

Followed by a function to properly fetch the application URL.

Works perfectly.

Chris
  • 621
  • 1
  • 5
  • 7
0

Take a look at the UriBuilder class. You can create one with a url string, and the object will then parse this url and let you access just the elements you desire.

DanDan
  • 10,462
  • 8
  • 53
  • 69
0

I'm guessing that you want to do this because you want your users to see pretty looking URLs. The only way to get the client to "change" the URL in its address bar is to send it to a new location - i.e. you need to redirect them.

Are the query string parameters going to affect the output of your page? If so, you'll have to look at how to maintain state between requests (session variables, cookies, etc.) because your query string parameters will be lost as soon as you redirect to a page without them.

There are a few ways you can do this globally (in order of preference):

  • If you have direct control over your server environment then a configurable server module like ISAPI_ReWrite or IIS 7.0 URL Rewrite Module is a great approach.
  • A custom IHttpModule is a nice, reusable roll-your-own approach.
  • You can also do this in the global.asax as you suggest

You should only use the 301 response code if the resource has indeed moved permanently. Again, this depends on whether your application needs to use the query string parameters. If you use a permanent redirect a browser (that respects the 301 response code) will skip loading a URL like .../default.aspx?utm_source=twitter&utm_medium=social-media and load .../default.aspx - you'll never even know about the query string parameters.

Finally, you can use POST method requests. This gives you clean URLs and lets you pass parameters in, but will only work with <form> elements or requests you create using JavaScript.

dariom
  • 4,413
  • 28
  • 42
  • If you want users to see pretty looking urls, why not just use URL Mapping? – Mark Maslar Jul 27 '09 at 15:08
  • URL Mapping might work, but you need to define a mapping for every page in your web.config file. You can't define general rules. Still, if there aren't many pages in the site, configuring these once might work nicely. On the other hand URL rewriting gives you more control. – dariom Jul 27 '09 at 15:44
  • He's doing it to add canonical links and consolidate page rank, not for url rewriting purposes:http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html – Matt Evans Apr 21 '11 at 14:42
-3

After completing whatever processing you need to do on the query string, just split the url on the question mark:

Dim _CleanUrl as String = Request.Url.AbsoluteUri.Split("?")(0)
Response.Redirect(_CleanUrl)

Granted, my solution is in VB.NET, but I'd imagine that it could be ported over pretty easily. And since we are only looking for the first element of the split, it even "fails" gracefully when there is no querystring.

Andro Selva
  • 53,910
  • 52
  • 193
  • 240