Howto get the actual url with (C#)

Hello there,

I seem to have a problem getting the actual url from within my pages.

When I type in [i]http://localhost/foobar/?foo=bar[/i] and try the following code:

<% = Request.Path %>
<% = Request.RawUrl %>
<% = Request.ServerVariables["URL"] %>
<% = Request.Url.AbsolutePath %>

I get this result:


Now. From my point of view there is at least two errors here.

  1. I did not request [i]http://localhost/foobar/Default.aspx?foo=bar[/i]. But… NO. I did NOT request Default.aspx (and I did not have sex with that woman either :wink: ). But I am a smart .net-framework and I know… NO! I don´t use you for being smart. I use you to do what I want.
  2. My default index page is named default.aspx NOT Default.aspx.

What property/method must I use to get the actual URL? And on what object?

Now I have written a custom method returning the result of Request.Path.Substring(0, Request.Path.LastIndexOf(‘/’)) but hey! There must be some property or method in native .net that returns what I want.

Hate to break it to you, but did request Default.aspx. Requesting no document automatically forwards you to the default document when one is set. IIS is case insensitive, so Default, default and DEFAULT are all the same. And, when one installs ASP.NET, IIS adds “Default.aspx” to the default documents list.

Look at the Request.Path object for just about anything related to the path of the request.

I know all these things: That Windows and therefore IIS case-insensitive. That adds Default.aspx to IIS default documents list. I also know that Request.Path returns string so I can´t look for properties/methods on that property.

The question is if there is any way to get the actual request from the client. The client don´t append Default.aspx, that´s for sure. When I monitor the HTTP-traffic I can clearly see that the client requests [i]http://localhost/foobar/?foo=bar[/i]. IIS and/or must have this request somewhere otherwise they really have issues.

You did not quite follow me.

  1. Client requests http://localhost/foobar/
  2. IIS says, gee, look, I have a Default.aspx in the default docs and there is a default.aspx in the folder. Lets append that. If there is no default doc, it will try and do a directory listing.
  3. By the time the request gets to ASP.NET, it has been changed to http://localhost/foobar/Default.aspx .

If you look in the IIS logs, not in the HTTP traffic, you will see that this is the case. There are no requests for /, unless you have no default doc and directory browsing is allowed.

For all intents and purposes, http://localhost/foobar/Default.aspx is the actual request from the client. They just are not quite expressing it that way. Remember that ASP.NET needs that .aspx appended or it would never process the request anyhow.

Also, Request.Path was the wrong answer above. Try Request.Url.

Yes. I know the process but if they have been smart they should have implemented step 2 like this:

  1. _
  2. IIS says, gee, look, a request for a default doc. I have a Default.aspx in the default docs and there is a default.aspx in the folder. Lets save the original request in HttpRequest.OriginalRequest (or something like that). Lets append that. If there is no default doc, it will try and do a directory listing.

If they don´t save original request somewhere they should implement it as soon as possible as it will be very hard to implement methodologies like friendly URLs if they keep on screwing with requests. Not that MS ever has expressed great sympathy for things like usability etc. :frowning:

Off Topic:

Someone at MS (probably the one that implemented System.Uri) has really screwed up.

From the Remarks on Uri.Fragment Property description:

The Fragment property gets any text following a fragment marker (#) in the URI, including the fragment marker itself. Given the URI, the fragment property would get #main.

Well does it? Don´t think so :rolleyes:

Requesting: http://localhost/foobar/?foo=bar#foobar

Executing: <% = Request.Url.Fragment %>


Nothing. Ohh. No, sorry. Not nothing. Empty string I mean.

You could try this in your global.asax:

protected void Application_BeginRequest(Object sender, EventArgs e)

Application_BeginRequest is fired each time a request is made but before fulfilling it.

wwb is right though - you are requesting default.aspx (by default) when you don’t specify a file. If you specify another page then you’ll see that page name instead.

I don´t agree with you. I, as in the user write i an URL i the adress field and hit Enter request the adress I write in. No more, no less. The user is not interested what the default document is named or what technology the server is using, will it be .aspx, .php or whatever. If I bookmark it will work no matter the technology, but will not work if/when the company switches to PHP, Java or whatever. Or some administrator renames the default document.

In a tech perspective I don´t agree with you either cause the client browser request the URL it transmits in the request. no more, no less. THEN the webserver is manipulating it and forwards the request to

So for the request for looks like this:

user --> client --> server -->
      ^          ^          ^
      1          2          3

  1. Request is still
  2. Request is still
  3. Request has been manipulated. It´s now

I really don’t care whether you agree or not.

IIS has a list of default documents which have default settings + you can add any other files you wish. If a request is made and a file is not specified it runs down that list till it finds one of those files in the folder, and it assumes that’s the desired file. If it doesn’t find any of the listed files it’s a 404.

So, user requests

IIS looks at its list of ‘default’ pages which (by default) consist of:

If any of those files exist then it assumes that’s what you’ve requested, so that’s what it serves. If it’s the spelling that’s throwing you off, you requested “default.aspx” and it gave you “Default.aspx” then you can adjust those default documents in the Documents tab of the sites properties in IIS.

If/when [company] switches to PHP/Java whatever then obviously someone is going through the code anyway, and catering for IIS-specific logic is going to be dealt with, so it’s a non-issue anyway.

I would add that the behavior is absolutely consistent, so easy to code around. As for wayward admins changing settings: you did document the fact that default docs should be left at whatever you want them left at, no? Admins are very good at reading manuals before screwing with live servers.

I also would argue that IIS/ASP.NET’s behavior is correct. It is telling you the actual document requested. Remember that IIS is little more than a phone book. It takes a request, looks it up, and forwards it to the appropriate party. If it never stuck in the defaultdoc.aspx it would have no idea which processing engine to pass it off to. IIRC, apache behaves the same way.

If you absolutely must have the url, the raw HTTP request is avaliable (HttpRequest.InputStream and HttpRequest.Headers. See also HttpRequest.RawUrl which might work for you). You should be able to get what you want from there.

If you are looking at Url Rewriting, there are two very good options for .NET. First is trusty old IIS Rewrite, second is a neat little regex based HttpHandler that can do the trick.

Furthermore, if you are changing platforms, you have alot more to worry about than some user’s bookmarks. Even if you are changing back ends within the same platform, you are going to easily wreak havoc on external links and have to deal with it in some way.

Well. This is all and well and i really actually truly know this already :rolleyes: I´m not a newbie so please don´t act as you think I am.

Yes. And there is where it should stop doing things also. Just serve! NOT manipulating the HTTP client request. The IIS is acting like a stupid proxy in this case, and this is what the HTTP RFC has to say about that:

A transparent proxy MUST NOT rewrite the “abs_path” part of the received Request-URI when forwarding it to the next inbound server, except as noted above to replace a null abs_path with “/”.

If you do the same on Apache using for example PHP you will get the following CORRECT answers when requesting http://localhost/foobar/?foo=bar:

REQUEST_URI: /foobar/?foo=bar
HTTP Request: GET /foobar/?foo=bar HTTP/1.1

EVEN if you put up default.php default.html index.php index.html in Apaches ‘default document list’ a.k.a. DirectoryIndex.

This is more close to the HTTP RFC as it states in chapter 14.23:

For example, a request on the origin server for <; would properly include:

   GET /pub/WWW/ HTTP/1.1

But then again. Microsoft has never been very good at reading these documents it seems.

No. It´s not the spelling. I don´t actually care about that.

This is often not a very good solution. The administrator would have to add Deafult.aspx to the DirectoryIndex list and/or make a rewrite or redirect to he proper DirectoryIndex file, unnecessary stealing a small amount of performance.

Maybe it the ppl implementing the HttpRequest.Url in .net was in a hurry and didn´t have time to do it right (happens on all companies, why not on MS?). With managers breathing down your neck it´s probably easy to check in some unfinished code and then ‘forget’ about it. I know it happens on all the places I´ve been so far.

Not as I see it or as I interpret the HTTP RFC.

I am not interested in what actual document was requested. I am interested in the actual HTTP REQUEST URI!!! How IIS and works internally is not in my interest. They should work it out some other way.

I agree. It´s a little more than an phone book :wink:

No. See my post above.

Thanks. I will test this :slight_smile:

Already tried that. It´s all manipulated already.

Read my first post in this thread.

Depends upon where you put focus. You should read more about the concept friendly URLs.

Why don’t you just change the default page? If you request /?bla the request has to point at some file anyway, and you must surely have an idea what file the person should be trying to request.

Alternatively you can setup a 403 error page, remove the default documents, and this is what my test resulted in:
Request.Url.PathAndQuery = /403.aspx?403;http://test.srv:80/?asdfasdfdasf

From that you could identify whatever it is you’re not able to identify now, and then redirect them to wherever they’re supposed to go.

I thank you both for input, feedback and help upon this matter but I guess I´ll stick with my ‘hack n´ slash’-method. Is there some way to get the ‘default document list’? Maybe as a string array with file names?

You could examine the IIS metabase which is an XML file holding its configuration - that requires a bit of access to the server though.
It can be found at C:\WINDOWS\system32\inetsrv\MetaBase.xml

If you’re on shared hosting or don’t have access just request the list - it won’t change unless someone goes in and alters it (in theory).

The list I mentioned above is the default for IIS6 + .NET Framework, from memory IIS5 was the same - you could test that in XP though.