Scott on Writing

Musings on technical writing...

Mapping All File Extensions to ASP.NET

In my article URL Rewriting in ASP.NET I showed how to use URL rewriting to allow for rewriting from a “pseudo” URL, like /Products/Meat.aspx, to a real URL, like /ListProducts.aspx?CatID=1.  (By “pseudo” I mean that on the Web server the file /Products/Meat.aspx doesn't exist.  Rather, when the request comes in for that file and is handed to the ASP.NET engine, the ASP.NET engine examines user-defined rewrite rules to determine to (behind the scenes) rewrite the incoming requested URL to /ListProducts.aspx?CatID=1, which does exist and displays the meat-related products.  The benefit to the user - they get to see/use a memorable URL, one devoid of messy querystring parameters.)  Additionally, if a user visited the directory /Products/ (or /Products/default.aspx), the user would see a list of the product categories.

One of the subtleties of this approach is that while the file /Products/Meat.aspx did not really need to exist, the directory /Products/ needed to exist in order to serve requests to /Products/ (but not to /Products/default.aspx).  Why?  Because if a user entered into their browser www.yoursite.com/Products/, IIS would handle the request and not hand it off to the ASP.NET engine.  IIS would say, “Hey that directory doesn't exist,” and return a 404 HTTP response.  (The request to /Products/default.aspx would work because IIS would hand off the request to the ASP.NET engine since the request was clearly for an ASP.NET resource - default.aspx.)  Therefore, to implement this end user-friendly URL scheme, you would need to create a /Products/ directory and a dummy default.aspx.  That way, when a request came in to /Products/, IIS would say, “Yes, that directory exists.  And yes, it has a default.aspx file, so let me hand off the request to the ASP.NET engine.”

In my article I discussed a workaround to needing to create these “dummy” directories was to map all incoming requests from IIS to the ASP.NET engine.  This way, even a request for /Products/ will get routed to the ASP.NET engine without IIS checking to see if /Products/ exists and if there is a default.aspx file in that directory.  Unfortunately, completely implementing this solution is not just as simple as flipping the switch on IIS to pass all incoming requests to the ASP.NET engine.  In fact, there has been a good discussion on my previous blog entry announcing the URL rewriting article.  Some of the problems noted is that the default page for a directory won't load.  That is, a request to /Products/ won't bring up /Products/default.aspx.  Also, requests to non-ASP.NET files - such as images, CSS classes, external JavaScript files, etc. - don't work.

The problem arises because all requests are being mapped to the ASP.NET engine.  Requests to image files.  Requests to CSS files.  Requests to just the directory path /Products/ (not /Products/default.aspx).  So, if you want to use this approach of mapping all files to the ASP.NET engine, you're going to have to make the ASP.NET engine a bit smarter (and tell it how to handle all of the potential file requests that might come in).  This is most easily done by creating HTTP handlers for different types of content that might need to be served.  For example, you could create an HTTP handler that would know how to serve content like images, CSS files, external JavaScript files, etc.  Your “catch-all” handler would need to know that if a request came in that looked like /Products/, that it would have to append default.aspx to the request and retry.

To get a good understanding of how to accomplish this, check out the .Text source code.  In the Configs/Multiple1_Web.config file you can see an example of mapping image/CSS files to a static HTTP handler:

<HttpHandler pattern = "(\.gif|\.js|\.jpg|\.zip|\.jpeg|\.jpe|\.css)$" type = "Dottext.Common.UrlManager.BlogStaticFileHandler, Dottext.Common" handlerType = "Direct" />

In Code/Dottext.Common/UrlManager/BlogStaticFileHandler.cs you can see how static content (images/CSS files/ZIP files) are served.  In Code/Dottext.Common/UrlManager/PageHandlerFactory.cs you can see how directory requests - like /Products/ - are handled.  There's even examples of URL rewriting at work in Code/Dottext.Common/UrlManager/UrlReWriteHandlerFactory.cs class.

The point is, if you map all requests to the ASP.NET engine, then you have to essentially replicate the work IIS does through custom HTTP handlers.  Hope this helps some folks struggling through mapping all requests in IIS to the ASP.NET engine!

posted on Sunday, March 28, 2004 3:19 PM

Feedback

# re: Mapping All File Extensions to ASP.NET 3/28/2004 6:57 PM G. Andrew Duthie

And don't forget that mapping *all* requests to ASP.NET, particularly those for static content, has performance implications, since IIS is much more efficient at serving static content such as .htm files and images, provided that they exist in the filesystem. So if you only want to provide partial URL rewriting, mapping everything to ASP.NET might not be the most efficient solution.

# re: Mapping All File Extensions to ASP.NET 3/29/2004 12:42 AM Mike Schinkel

Scott, thanks for taking the time to blog about this. Yours was the first time I've seen anyone address the entire subject. That said, who that's bloggin within MS should be asked about this (hopefully to see a better solution from MS in the future)?

# re: Mapping All File Extensions to ASP.NET 3/29/2004 6:30 PM Johnny Dev

Scott,

Any plans on writing another article with support for dynamic directory names without them existing? I tried to figure it out by looking at the Source for .Text but I didnt get very far. I only got as far as the static files. I couldnt get .Text to run in multi-blog mode - I kept getting an error and spent too much time trying to figure it out. So I couldnt find the regular expressions for the dynamic directories.

# re: Mapping All File Extensions to ASP.NET 3/30/2004 10:52 AM Mark Dicken

Sir Scott... (The Now Known Master Of Http URL Mapping Master!!! - Please help us all... - Please!...),

As 'Johnny Dev' has demonstrated, there are are number of people like me that simply want a simple solution to fix a simple problem, maybe this will help the creation of a Simple Application Block (Blue Brick!)

Like 'Johnny Dev' I simply want a simple routine that says the following :-

If URL = 'ShowDetailes/DirectoryAAA/UK/York' then I want to sent the values of 'DirectoryAAA/UK/York' to a page called 'ShowDetailes.aspx' with a query string of '/DirectoryAAA/UK/York'

Once again, I hope that I'm not asking too much from Microsoft Technologies ...

If it is asking too much then what off the shelf component can we purchase ??? or what sample code could we all customise ...

Cheers Dude in advance ....

Regards

Mark Dicken
http://www.MarkDicken.com
Mobile +966 5 483 9724
(Currently Working In Saudi Arabia...)

# re: Mapping All File Extensions to ASP.NET 3/30/2004 10:59 AM Scott Mitchell

Mark, what might be simplest is to do the URL rewriting at the IIS level. There are third party components available for this, where you can configure the redirection using a Windows app on the Web server. Some to check out include:

ISAPI Rewrite - http://www.isapirewrite.com/
IIS Rewrite - http://www.qwerksoft.com/products/iisrewrite/

You might also want to give this a look see:
http://www.port80software.com/products/pagexchanger/

FYI, I've not used any of these products myself........

# re: Mapping All File Extensions to ASP.NET 3/31/2004 12:38 AM Kenneth

We just have to accept that URL rewriting is a weak part of ASP.NET. Sad, but true...

# re: Mapping All File Extensions to ASP.NET 4/1/2004 1:33 PM Mark Dicken

Sir Scott,

Thanks for the feedback, I'll have a look into the 3 mentioned products. BUT I have a feeling that for a 'Shared Server Space' Solution that NONE of them will be of use without a Dedicated Server ... these maybe of use for many people but it's a pity for the other 70%+ of ASP.NET developers ...

... Hopefully this area will be addressed in 'future versions'...???

I'll have another look at the 3 products.

What about utilising the ERROR 404 ability and using that - does it make a hugh performance nose dive??? - someone quoted on RAC (RentACoder) that they have done a simple solution that did not seem to be a performance issue.

Regards

Mark Dicken

# re: Mapping All File Extensions to ASP.NET 4/1/2004 2:39 PM Scott Mitchell

Mark, you'll have trouble using those products on a shared server, unless you know someone at the Web hosting company. :-)

Regarding the 404 approach, it would work fine as long as the ASP.NET engine got its hands on the incoming request. So, it would still not work when you have a request to something like: /Blah/FakeDir/, where /FakeDir/ does not exist. IIS will, in this instance, return a 404 and you won't get to have ASP.NET's custom errors handler pick it up... (I assume this is what the RAC fellow was propsoing...)

# re: Mapping All File Extensions to ASP.NET 4/28/2004 12:58 AM sandeep

hello sir,
i read your article on URL rewriting in asp.net on msdn.i have also used the same in my project.URL rewriting is working fine in our LAN and on our configured IP but problem is that when we host our site to some ISP its not working and giving error like this "THE PAGE CAN NOT BE FOUND" its really emberrasing because i am not able to find out the proble any where
i am seding the code which i am using
Sample code
==================
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' Fires at the beginning of each request
Dim context As HttpContext
context = HttpContext.Current()
Dim strOldPath As String
strOldPath = Trim(context.Request.Path.ToLower())
Dim strToken As String
strToken = "accomodationdetail"
Dim intI As Integer
intI = strOldPath.IndexOf(strToken)
Dim intLen As Integer
intLen = strToken.Length
Dim intJ As Integer
If intI <> -1 Then
intJ = strOldPath.IndexOf(".aspx")
If intJ <> -1 Then
Dim strDetail As String
strDetail = strOldPath.Substring(intI + intLen, intJ - (intI + intLen))
Dim strNewPath As String
strNewPath = strOldPath.Replace(strToken + strDetail + ".aspx", "AccomodationDetail.aspx?intID=" & strDetail)
context.RewritePath(strNewPath)
End If
End If
end sub
============================

but when i called some page like this

original request=/accomodation/accomodationdetail22.aspx
after rewrite=/accomodation/accomodationdetail.aspx?id=22
above request is doing fine in our lan and on our configured IP
but not working on ISP where we host our site
and giving error "THE PAGE CAN NOT BE FOUND"
i think you got my problem
please help me as soon as possible
thanks
regards
sandeep
MY MAIL id IS spandit@rsbsystems.com

# re: Mapping All File Extensions to ASP.NET 9/6/2004 3:21 AM Leeds Web Designer

Hi,

I have arrived here because I have implemented a URLRewriter using HttpModules on some websites I am developing. I have mapped all extensions to ASP.NET and it is working OK but all other file types are now broken.

I do want to be able to provide domain.com/thename type urls but do not want to create directories for each item.

I have experimented with a couple of approaches to the url rewriting. They all have their pros and cons. I have implemented a 404 type system which didnt actually rewrite the URL, but did handle addresses without an aspx extension. If you set up custom errors on your hosting and that 404 page is an aspx page then it gets passed to asp.net.

# re: Mapping All File Extensions to ASP.NET 9/14/2004 10:38 AM Matt

Kudos to ya on that article, Scott. Without a doubt the best treatment of URL Rewriting I've seen yet. Like it's been said, the solution with new subdirs isn't perfect, but it gets your foot in the door. Good enough for me.

# re: Mapping All File Extensions to ASP.NET 9/21/2004 11:18 AM Daniel Fisla

I have a similar problem. I have deployed DotText on our intranet and everything works fine with the multiblog config with URLs like blogs.domain.com/user.

When hosted in production I keep getting 404s when requesting http://blogs.domain.com/user or http://blogs.domain.com/user/

Only, http://blogs.domain.com/user/default.aspx works. I've spend days now researching this to no avail.

I've tested this on multiple systems and keep getting the same 404 error. The code only works on my dev box. I spent days trying to make sure all boxes are the same OS and config, Server 2003 with IIS 6.

Please help if you can. :-)

dfisla@hotmail.com

# re: Mapping All File Extensions to ASP.NET 11/26/2004 4:42 AM Martin Hinshelwood

Hi,

I am trying to get IIS6 to map all requests to the ASP.NET engine, but when I try to map the extention * or *.* I get a wee popup bubble that sais that it is not valid!

How do you set IIS on Windows 2003 to map all requests to ASP.NET?

Marv

# re: Mapping All File Extensions to ASP.NET 1/4/2005 7:50 PM Dino

URL Rewriting is much more easily done within an ISAPI filter. It is general and you need not map everything to ASP.NET.

example
http://cheeso.members.winisp.net/dl/IonicIsapiRewriter.zip

# re: Mapping All File Extensions to ASP.NET 3/4/2005 12:47 PM Stephen Bauer, MD

Any input on with isapi solution is the most robust, reliable, and compatible (W2K3/IIS6)?

# re: Mapping All File Extensions to ASP.NET 6/29/2005 7:07 PM Paul

Regarding the 404 approach, Scott said:

"Regarding the 404 approach, it would work fine as long as the ASP.NET engine got its hands on the incoming request. So, it would still not work when you have a request to something like: /Blah/FakeDir/, where /FakeDir/ does not exist. IIS will, in this instance, return a 404 and you won't get to have ASP.NET's custom errors handler pick it up... (I assume this is what the RAC fellow was propsoing...)"

I know this not to be true. I use a scheme for file downloads in which the URL is /download/{guid}/filename.ext". The {guid} directory does not exist, but I have 404's mapped to /download/main.download and an HttpHandler configured to handle files w/ the extension .download. The handler obtains the guid and uses it to obtain state information from the web cache as to what file to then stream out to the user. Again, this works fine...and I think the key is to map the custom error to a URL not a File.

All of that being said, is this not a viable solution to URL rewriting in ASP.NET w/out creating the directories and w/out handling static files ( .jpg, .gif, .css, etc)?

# re: Mapping All File Extensions to ASP.NET 6/29/2005 7:19 PM Scott Mitchell

Paul, the difference is that you're example *ends* with filename.ext. What you quoted is saying that if the request ends with a directory that does not exist. That is, imagine {guid} does not exist - then your custom ASP.NET Handler will not get a chance to run if the user attempts to visit /download/{guid}/ because IIS will say, "Wait a sec., {guid} doesn't exist," and handle the 404. But it wouldn't hand off the 404 to ASP.NET's configured 404 error handler b/c IIS doesn't know that {guid} is an extension to hand off to ASP.NET. It works in your instance b/c the request is to filename.ext, and .ext is mapped to ASP.NET. So IIS says, "Oh, 404, here, this is for you, Mr. ASP.NET engine."

# re: Mapping All File Extensions to ASP.NET 8/3/2005 4:35 PM Sean Kinsey

The last comment is somewhat errouneous as it is quite possible to rewrite RawURLs containing only a foldername using a 404 handler.
You simply use a custom 404(GET)/405(POST) page, have IIS call the URL /404handler.aspx, not the FILE (as this is not parsed the same way then).
The 404handler.aspx page will then be able to extract the orginial url that was asked for from the querystring.
I have not tried this combined with urlRewriting but I think that it should be somewhat helpfull.

# re: Mapping All File Extensions to ASP.NET 8/9/2005 3:10 AM Sean Kinsey

I have found a perfect and simple solution to the problem of having to make httphandlers for all filetypes when mapping everything to the aspnet_isapi.dll.
On the main application folder i specified that .* should sent to the aspnet_isapi. I then continued to create a subfolder which I also defined as an application. I then removed the .* mapping from this 'subapplication'.
Now I just place all my static content (images, document, media) in this folder and everything works as a charm!

# re: Mapping All File Extensions to ASP.NET 10/11/2005 8:15 PM Scott Hanselman

Why not use System.Web.StaticFileHandler? Why did you use a custom one from dottext?

# re: Mapping All File Extensions to ASP.NET 10/27/2005 3:42 PM Ian

Sean Kinsey, that sounds more like it. Noticed any draw backs?

# re: Mapping All File Extensions to ASP.NET 1/10/2006 9:09 AM Steph

I implemented your solution (kind of, made some modifications) and like you said, it doesn't work when you just have the foldername/ with no page name. One of your suggestions is to create a folder and put a default.aspx page in each folder which obviously is a pain. If I just make the link go to foldername/default.aspx without the folder existing though, the code seems to still work. But I have to make sure the path just includes some kind of pagename with the .aspx extension so that it knows to go to the asp.net. Do you see any drawbacks to this? Also, please forgive my ignorance, but how do I change IIS to make every page map to the asp.net engine so I can try to implement your suggestion above. So that if the user types foldername/ - it knows to map to asp.net engine? Thanks!

# re: A great tutorial on a hack 2/7/2006 4:00 AM Pete

I found this tutorial while trying to overcome the dir problem. I have successfully set it up using Scott's original code.

It works a treat, even though it may not be the most straightfroward method.

You need access to IIS however, so not for 3rd party hosting unless they are gracious enough to let you alter your IIS setting.

# re: Mapping All File Extensions to ASP.NET 2/7/2006 4:01 AM Pete

Oops ... posted it as my name url...

http://www.minwar.com/126

# re: Mapping All File Extensions to ASP.NET 4/1/2006 10:16 AM Will Asrari

I've created a URL rewriting solution via Global.asax that eliminates filename extensions. Instead it uses a "slug" as a unique identifier to rewrite the path.

http://www.willasrari.com/blog/rewrite-url-without-using-filenames-or-extensions-c/000109.aspx

# asp.net c# - requested string 4/17/2006 9:00 PM hernann

if I have the Url resul.aspx?cat=DB ?

I wanna to get the DB in result page , how ???

# re: Mapping All File Extensions to ASP.NET 4/30/2006 1:50 PM Jacob Jensen

Hi... i finally, after 3 days hard work, find this article, but i cant get it to work. So i were hoping some of you might help.

The problem is, that my css, pics and so on dont show when i enable the urlrewriter..

I jused :
http://www.developerfusion.co.uk/show/5302/

for rewriting, and removed the "action" attribute of the HtmlForm, for functional postback's..

Then i put Dottext.Common.dll in my /bin/ folder, and put :

<HttpHandler pattern = "(\.gif|\.js|\.jpg|\.zip|\.jpeg|\.jpe|\.css)$" type = "Dottext.Common.UrlManager.BlogStaticFileHandler, Dottext.Common" handlerType = "Direct" />

in my web.config... but where do i have to place it ? it gives me an error..

Sorry my poor english, but please help :)

Best regards
JAcob Jensen, DK

# re: Mapping All File Extensions to ASP.NET 6/21/2006 12:11 AM Jose

Hi,

I have implemented the URL rewriting code but find myself with the problem you descibed with images, css and other static files. Rather than implement a solution like .Text (route everthing to .NET and provide handlers for all) would it be possible to modify the output using Regular Expressions? This would simply convert all relative paths to absolute paths. Is it a good idea? Any help would be appreciated.

Thanks,
Jose

# re: Mapping All File Extensions to ASP.NET 2/10/2010 5:24 PM renantech


I found your blog on Google and read a few of your other posts. I just added you to my Google News Reader. Keep up the good work.

I found aspx file extension can really crawl faster

# re: Mapping All File Extensions to ASP.NET 3/17/2010 6:07 AM Gabby

One of your suggestions is to create a folder and put a default.aspx page in each folder which obviously is a pain. If I just make the link go to foldername/default.aspx without the folder existing though, the code seems to still work.

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<March 2010>
SMTWTFS
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Comment Stats

DayTotal% of Total
Sunday 2056.8%
Monday 42514.1%
Tuesday 51917.2%
Wednesday 55618.4%
Thursday 58019.2%
Friday 54718.1%
Saturday 1886.2%
Total 3020100.0%

Hour1Total% of Total
12:00 AM 782.6%
1:00 AM 812.7%
2:00 AM 682.3%
3:00 AM 822.7%
4:00 AM 692.3%
5:00 AM 1264.2%
6:00 AM 1193.9%
7:00 AM 1816.0%
8:00 AM 1926.4%
9:00 AM 1585.2%
10:00 AM 1886.2%
11:00 AM 1936.4%
12:00 PM 2016.7%
1:00 PM 1846.1%
2:00 PM 1695.6%
3:00 PM 1354.5%
4:00 PM 1153.8%
5:00 PM 1073.5%
6:00 PM 1013.3%
7:00 PM 1073.5%
8:00 PM 923.0%
9:00 PM 882.9%
10:00 PM 913.0%
11:00 PM 953.1%
Total 3020100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 5.00160
Monday 4.80384
Tuesday 4.04477
Wednesday 7.39680
Thursday 6.26676
Friday 5.07466
Saturday 4.78177
Total 5.403020

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 3.8550
8:00 AM 3.72134
9:00 AM 6.06297
10:00 AM 5.63276
11:00 AM 4.22194
12:00 PM 6.16351
1:00 PM 3.09133
2:00 PM 4.89230
3:00 PM 7.67322
4:00 PM 4.00108
5:00 PM 6.07170
6:00 PM 4.64116
7:00 PM 8.95188
8:00 PM 8.63164
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.403020

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles