Click here to Skip to main content
Click here to Skip to main content

Serve Extensionless URL Without Using ISAPI Handler or Wildcard Mapping

By , 11 Jun 2011
 

Problem

If you want to serve extensionless URL from ASP.NET 2.0 like the following:

  • www.store.com/books
  • www.store.com/books/asp.net2.0
  • www.forum.com/post/how-to-serve-extensionless-url

You cannot, unless you use some third party ISAPI module or use IIS 6.0 Wildcard mapping feature. Third party ISAPI module needs to be installed on the server directly. If you don't have a dedicated server or a Virtual Private Server where you can install an ISAPI module, you cannot take this approach. Moreover ISAPI modules intercept each and every request, so the more modules you install, the slower each request becomes. On the other hand, IIS 6.0 Wildcard mapping makes each and every request go through ASP.NET 2.0 ISAPI handler including URLs with .gif, .css, .js, .html, etc. So, it suffers from scalability problem. Some independent research shows there's 30% drop in performance in IIS 6.0 when you use wildcard mapping. So, this is not a good solution either.

Solution

Here's an approach which works without using ISAPI module or wildcard mapping in IIS 6.0. When you request extensionless URL, you get HTTP 404 page. This means IIS receives the request and it serves the page configured for HTTP 404. Generally this is a 404.html file that resides in IIS directory. IIS does not send the request to ASP.NET handler and thus you cannot intercept 404 requests. So, if you can forward all HTTP 404 to ASP.NET, you can serve such extensionless URL. In order to forward HTTP 404 to ASP.NET ISAPI, all you need to do is configure IIS to redirect to some .aspx extension when a missing extensionless URL is hit.

Benefits of this approach:

  • No third party ISAPI module required. Thus no installation problem, no request interception delay
  • No Wildcard mapping thus no performance sacrifice for ASP.NET

Here's how to configure 404 redirection in IIS 6.0:

On IIS 6.0, change 404 default page to /404.aspx and the type to "URL". On IIS 7.0, change 404 default page to /404.aspx and the type to "ExecuteURL". Also, change the default error response to "Custom error pages".

iis7.png

When you will request a URL like "www.shop.com/products/books" it will redirect to "www.shop.com/404.aspx?404;http://www.shop.com/products/books". From Global.asax BeginRequest event, capture this URL and see whether it's an extensionless URL request. If it is, do your URL rewriting stuff for such extensionless URL.

   1: protected void Application_BeginRequest(object sender, EventArgs e)
   2: {
   3:     string url = HttpContext.Current.Request.Url.AbsolutePath;
   4:
   5:     // HTTP 404 redirection for extensionless URL or some missing file
   6:     if (url.Contains("404.aspx"))
   7:     {
   8:         // On 404 redirection, query string contains the original URL in this format:
   9:         // 404;http://localhost:80/Http404Test/OmarALZabir
  10:
  11:         string[] urlInfo404 = Request.Url.Query.ToString().Split(';');
  12:         if (urlInfo404.Length > 1)
  13:         {
  14:             string originalUrl = urlInfo404[1];
  15:
  16:             string[] urlParts = originalUrl.Split('?');
  17:
  18:             string queryString = string.Empty;
  19:             string requestedFile = string.Empty;
  20:
  21:             if (urlParts.Length > 1)
  22:             {
  23:                 requestedFile = urlParts[0];
  24:                 queryString = urlParts[1];
  25:             }
  26:             else
  27:             {
  28:                 requestedFile = urlParts[0];
  29:             }
  30:
  31:             if( requestedFile.IndexOf('.') > 0 )
  32:             {
  33:                 // There's some extension, so this is not an extensionless URL.
  34:                 // Don't handle such URL because these are really missing files
  35:             }
  36:             else
  37:             {
  38:                 // Extensionless URL. Use your URL rewriting logic to handle such URL
  39:                 // I will just add .aspx extension to the extension less URL.
  40:                 HttpContext.Current.RewritePath(requestedFile + 
					".aspx?" + queryString);
  41:             }
  42:         }
  43:     }
  44: } 

The above code finds the virtual directory name e.g. /omar that was requested but resulted in HTTP 404. From the redirected URL, it parses and finds the missing folder name. From there, it rewrites the folder to a .aspx file extension which can handle the request for the missing URL. You can do different actions like rewrite to Default.aspx with the query parameters, redirect to another page and so on.

We have used this approach in Pageflakes. You can visit URLs like www.pageflakes.com/omar and get the URL handled by our homepage.

This solution is search engine friendly because no one ever sees a HTTP 404. You can test this using tools like Fiddler and see the missing URL hit will not produce HTTP 404 or any redirect. The response header will be HTTP 200 and the rewritten page content will appear as response body. So, there's no issue with search engine optimization (SEO).

Things To Watch Out

Missing Graphics, CSS and JavaScript

Browser thinks the missing URL is a folder and thus requests all relative files (graphics, css, js) from that URL. So, if you have a graphics at images/test.gif location of your site and you visit www.pageflakes.com/omar URL, then browser will request the graphics from www.pageflakes.com/omar/images/test.gif location.

Solution is to use a <base> tag and specify the correct location from where all relative URL is fetched. For example, you can set <base href="http://www.pageflakes.com/">. This will force browser to assume the page is being served from the root folder and thus translate all relative URL from the root URL. So, the graphics URL will be translated to www.pageflakes.com/images/test.gif which is the correct URL.

Postback Reveals Ugly URL

Another problem is related to postback. When you rewrite to an .aspx page, the form tag will be generated based on the .aspx page's path, not the path from where the URL was rewritten. For example, rewriting to somepage.aspx will render a form tag where the action attribute is set to somepage.aspx. So, a postback will redirect the browser to somepage.aspx.

You can use Scott Gu's solution from here.

AJAX Stops Working

When AJAX framework does not download from proper URL and async postbacks go to different URL than you intended, such problems happen. So, you need to use the <base> tag to produce the correct URL from where AJAX frameworks need to be downloaded and then rewrite form action tag to make async postbacks go to the correct URL.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Omar Al Zabir
Architect BT, UK (ex British Telecom)
United Kingdom United Kingdom
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Layout  Per page   
Questionabout url rewritingmember1234pankaj19 Jun '12 - 21:58 
it works with visual studio debug mod but when we run it on iis server it shows error source code 404 in iis7 . it not handle this error with your way which u shown here .please check & reply me.......
GeneralMy vote of 2memberHaBiX14 Jun '11 - 0:27 
imho its not a solution.. its an old trick that still needs alot of "addins" to make it work
 
you're breaking some of the http standards - unacceptable:
 
- how do you let SE crawler know that some file doesnt exist anymore (404)
- how do you let client know of 405 (the real one)
- how do i browse directorys on iis
- how do i use default document (IIS seting) mixed with your "url rewrite"
GeneralDirectory Listing Denied This Virtual Directory does not allow contents to be listed.memberRavenet22 Feb '10 - 22:45 
Hi,
 
I'm tried your solution is working fine in IIS 6, when we are test in IIS 7 wwe got above problem when i'm click my site top menu
 
for example , i have and url like this
 
Product-
 
Url -http://www.ctmart.com/proucts
 
this is will change like by url rewriting
 
http://www.ctmart.com/proucts/listofprod.aspx?id=09
 
that time i got Directory Listing Denied This Virtual Directory does not allow contents to be listed. this error, please help me to resolve.
 
thank you
RRave
MCTS,MCPD
All experts are welcome to http://codegain.com
 

 

GeneralPost BacksmemberYasin7530 Apr '08 - 7:09 
I have implemented your proposed solution.
 
I have used FormControlAdaptors as suggested by the links you gave to Scot Gu.
 
However, I canot post back to a url like www.domain.com/category/pagename.
 
I have a 405 error: Method not allowed.
 
Can you suggest a way out?
 
Thanks,
Yasin
GeneralRe: Post BacksmemberJohnStanfield28 May '08 - 8:13 
Do the same thing for the 405 page as you did for the 404.
GeneralRe: Post BacksmemberOzLand13 Aug '08 - 0:38 
I dont think is really working.
Can you really use postback?, i mapped the 405 in the ISS to the 404.aspx page, with no luck.
I am trying to deploy in a shared enviorement.
And this wont work???
Thanks
QuestionRe: Post Backsmember(A.D.)13 Oct '08 - 2:55 
We tried with this option and it worked fine when we tested it in our XP machines (IIS 5.1). But, when we deploy it in our IIS 6 server, it stops working.
 
We found a strange behavior (we could not justify it!), the HTTP POST requests for classic AJAX calls are getting converted to HTTP GET requests when we deploy the application in IIS 6. So, our AJAX calls are not returning any data from server. Any idea if there is any basic difference between these two IIS versions?
 
AD
AnswerRe: Post BacksmemberJ'Wise20 Nov '08 - 7:44 
I am seeing the exact same thing, something is up with IIS 6.0, IIS 5.1 seems to maintain the httpMethod, but IIS 6.0 for some reason or another seems to Change it a "GET" everytime. This poses a big problem for my situation. Is there any work around for this at all?
GeneralRe: Post BacksmemberJ'Wise25 Nov '08 - 9:04 
Hmmm... what more can you expect, the author no longer cares about this thread.
GeneralRe: Post BacksmemberOmar Al Zabir25 Nov '08 - 19:54 
IIS uses the 404 handler to redirect the request to another page. Since redirect is always GET, any POST is lost.
 
In order to compensate for the problem, you will have to change the form's action URL to the original URL.
 
So, if you are visiting:
 
www.pageflakes.com/omar
 
And IIS internally using the 404 handler to redirect to
 
www.pageflakes.com/default.aspx?userName=omar
 
Then the Form that's generated by the Default.aspx needs to have action URL set to:
 
www.pageflakes.com/default.aspx?userName=omar
 
Currently, it is set to www.pageflakes.com/omar
 
So, any postback goes to the 404 handler, which does a redirect (GET) and thus the POST information is lost.
 
Regards,
Omar AL Zabir
Visual C# MVP

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 11 Jun 2011
Article Copyright 2007 by Omar Al Zabir
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid