Extensionless Page Requests - asp.net

I have a customer of ours that sent out a publication referring to my site but they used the wrong address...they did not provide a page name...it looks like this:
mywebsite.org/Resources/toolkits/bridging
when it should have been
mywebsite.org/Resources/toolkits/bridging/default.aspx
Is there a way to tell ASP.NET to default to this default.aspx when it sees this kind of request or even better, have IIS 7 handle this easily?
This site is live so I would like to avoid having to introduce code if possible.

As per other suggestions, this should be done in the IIS configuration for your website using the IIS Admin tool.
There is however, another alternative - you can add a section in the web.config of your actual ASP.NET application, allowing you to override the IIS configuration right from your application:
<system.webServer>
<defaultDocument>
<files>
<clear />
<!-- Specify each of your files by order of preference here -->
<add value="Default.aspx" />
<add value="Index.aspx" />
<add value="MyOtherPage.aspx" />
</files>
</defaultDocument>
</system.webServer>
The caveat to this though is it may be a little obtuse when the IIS administrator can't figure out why the server configuration isn't working the way he's got it configured. It's not always right to do something just because you can.
Finally, just in case you don't have access to the IIS server or your IIS administrator has reasons for not adding Default.aspx to the default document list in the IIS configuration and for whatever reason, you don't wish to override the IIS configuration in your web.config file, then the quickest and simplest way is to simply create a file called default.asp in that directory containing:
<% Response.Redirect("default.aspx") %>
Default.asp is in the default document list on IIS. The code will automatically redirect the call to the correct page. The downside to this approach though is that there's a performance hit - every time someone calls default.asp - directly or otherwise, the redirect needs to happen which isn't free.

In the Documents tab of the web site properties in IIS you can specify default documents. If you are using .Net2.0 or later on that machine then Default.aspx should already be set....

Default.aspx is not, oddly enough, set as the default document in an IIS installation; In IIS 7, the setting is under "HTTP Features", called "Default Document". Add default.aspx to that list and you should be OK.
If not, you'll need to add a 404 handler that redirects when it sees that URL.

Related

IIS / ASP.NET: One URL returning 403 on one server despite other URLs in site working fine

I have taken over the maintenance of a production website at a new job that is written in ASP.NET 4 Webforms and that runs on IIS 6 on Windows Server 2003. I am not familiar with Webforms nor managing IIS...so I am kind of working things out as I go here.
I have done several deployments to our production server which have worked fine, but am now setting up a test environment that is identical, just a different IP address/domain, so we can properly test changes first.
I have a problem where on this test site any URL that does NOT end with a reference to a file (always .aspx on this site) will return a 403 error on this server. For example http://users.test.oursite.com/admin will always return a 403 error when logged into the site. It should be redirecting to http://users.test.oursite.com/admin/organisation.aspx. Having an MVC background I am not even sure how this happens...but it does in production.
Browsing links within the site is fine as they always reference an .aspx file. Manually typing URLS that reference an .aspx file is fine, just not when the URL does not contain a file. This is not a problem on the production server.
As I said, I am not familiar with WebForms or managing IIS itself...so I have kind of run out of places to look.
Is there anything that comes to mind that I should be looking at that could be causing this problem?
In WebForms typically there is no routing involved.
You need to either provide a full path on the URL ending with .aspx OR
setup default documents for your website. (Index.aspx, Default.aspx etc.)
http://www.iis.net/configreference/system.webserver/defaultdocument
OR
<configuration>
<system.webServer>
<defaultDocument enabled="true">
<files>
<add value="home.html" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
Default documents can be setup in IIS Properties or via web.config.
Otherwise you need to provide the full path.
And because you haven't setup the DirectoryBrowsing (in IIS), you get a 403 Error when you try to access the Directory.
Enable the Directory Browsing option in IIS (not recommended) if you want this error to go away.

Redirect a user when he or she tries to navigate to a page in ASP.NET website

Is it possible to re-direct a request for a page 'XYZ.aspx' to 'ABC.aspx', without writing any code? We are using ASP.Net 4.0 with IIS 7.5.
The idea is that we want to remove XYZ.aspx page from our website, and if users still use old bookmarks that point to XYZ.aspx, then we want them to be taken to ABC.aspx in an automated manner.
there seems to be a few ways, link should hopefully help you out.
http://www.trainsignal.com/blog/iis7-redirect-windows-server-2008
you can forward the user through web.config file or you can do it through IIS too. but I I were you I would use web.config. in shared hosting u cannot touch IIS.
I found the answer. One needs to use the following in web config, and that's it.
<location path="XYZ.aspx">
<system.webServer>
<httpRedirect enabled="true" destination="http://localhost/mysite/ABC.aspx" httpResponseStatus="Permanent" />
</system.webServer>
UPDATE : This will also work if any query string parameters are passed to the page XYZ.aspx.

IIS and Static content?

According to Ultra-Fast ASP.NET: Chapter 3 - Caching:
Files that the browser retrieves from the server should be stored in
the browser’s cache as long as possible to help minimize server
round-trips.
But how does IIS know what a static content actually is and is not?
Is it just images, CSS, JS and not ASPX, ashx...?
Where can I see in IIS what is already considered to be static and what is not ?
What about the scenario where a page has been declared with <%# OutputCache header (without location)? Are the images, CSS and JS source files inside of it also being output cached with the same properties?
As a best practice, I should set one year into the future as the maximum expiration time. I should use that as the default for all static content on the site
So I did this :
But later, after pressing OK, I can't find any summary menu which shows me: to whom I already put a response header (in this case: the css folder).
Currently, in order to see that css folder has been applied with response headers - I have to go to the css folder again --> Http Response Header-->Set Common Headers --> and then I see it. It isn't written in the web.config.
But if I do it for a file (Login.aspx for example): I do see it in web.config:
<configuration>
<location path="Login.aspx">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseExpires" cacheControlMaxAge="1.00:00:00" httpExpires="Fri, 15 Feb 2013 00:00:00 GMT" />
</staticContent>
</system.webServer>
</location>
</configuration>
I understand your situation. Sometime its confusing how IIS handles a file. Its also different for IIS 6 vs IIS 7 and different for Classic App Pools and Integrated mode app pools. My experience is mostly with Integrated App Pools on IIS 7.5, so thats the environment I can comment on most accurately.
First Question
But how does IIS knows what is actually a static content and what is
not?
Is it just images , css , js and not ASPX , ashx...?
Where can I see in the IIS what is already considered to be static and
what not ?
You can inspect the list of file handlers in IIS by navigating to your website and then click 'Handler Mappings'. By default these are inherited from the .Net base web.config which is in a different location depending on your .Net framework version.
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config
If a file being requested isn't already explicitly mapped to another handler it falls to a catch all handler (*) as the last option (System.Web.DefaultHttpHandler) which determines if it is a static file or a directory browsing request. So Static files are simply files not bound to another handler already. For example you'll see that *.aspx is already mapped to System.Web.UI.PageHandlerFactory prior to this default handler. So its going to be processed by that handler and not be considered a static file. If you removed that mapping you could technically serve *.aspx as a static file if you really wanted to (just for proof of how it works).
But you can also explicitly list a file type as a static file by adding an entry in your web.config's httpHandlers section mapping the file extensions to System.Web.StaticFileHandler in IIS. For example:
<configuration>
<system.webServer>
<handlers>
<add name="StaticHandler" verb="*" path="*.zip" type="System.Web.StaticFileHandler" preCondition="integratedMode" />
</handlers>
</system.webServer>
</configuration>
This example is using the <system.webServer> config section, so its for an App Pool running in Integrated Mode.
Second Question
What about the scenario where a page has been declared with <%#
OutputCache header(without location) . does the images,css,js src
files inside of it , are also being output cached with the same
properties?
No. Because the page is being server as a separate request (maybe even by a separate handler) it can have totally different cache headers/hints. The host page and the resources it may use are not related from a caching perspective.
In fact you may even want to have a shorter cache period for *.html and a longer cache period for *.jpg or *.png? Something to consider.
Third Question
As a best prcatice , I should set one year into the future as the
maximum expiration time.I should use that as the default for all
static content on the site
Hmm... I might not go as far as one year. How about one month? I would set a global policy like this:
<configuration>
<system.webServer>
<staticContent>
<!-- Set expire headers to 30 days for static content-->
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
</staticContent>
</system.webServer>
</configuration>
This is the same as the sample you showed above, but is not inside a <location> element, instead it is right in the root <configuration> element so it is the default policy. Again this is for an App Pool running in Integrated Mode. Sometimes you also need to turn on:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<!-- stuff -->
</modules>
</system.webServer>
<system.webServer>
This just makes sure that static files are processed through the managed static file handler which respects the above configuration elements.
Edit to Address Comments
The documentation for the configuration dialog you posted above is located here: Configure the HTTP Expires Response Header (IIS 7)
Apparently these settings are saved in C:\Windows\System32\inetsrv\config\applicationHost.config
I do not have IIS7 and personally develop on IIS 7.5 now. So please post a comment if you can verify this location is accurate!
The static content is the one that IIS is read and send to the browser with out any processing. There you can setup IIS to include some Cache-Control Header to cache it on clients browser computers.
You can do that ether by direct setup IIS, ether by commands on web.config as you say. The commands that you add on web.config and concern the IIS, did not have to do with asp.net it self, but the IIS, and IIS saves his configuration on a different file, so when you change that cache control headers direct on IIS you do not see them on web.config.
Now for the static content like images, CSS, JavaScript, and other similar files they say that you can follow the "never expire" policy by adding 10 years expire.
The issue here is that if you can not change the content of the static file, if for example you cache a javascript file with 10 years, and you make a small change on it, then you need ether to change the file name, ether to add some parameter at the end of it.
Now the <%# OutputCache on a control is referred to the server cache and not to the client, and what is actually do is to cache the render of the control on the server so the next time you ask it to not lose time to renders it again but read it from cache - is still send it to the browser.
And you can also read this answer for some more: What are difference between IIS (Dynamic and Static) cache,OutPutCache and browser cache

Why isn't my IHttpHandler being called?

I'm trying to get a custom handler to work for a specific URL (or set of URLs) in ASP.NET 3.5.
The handler doesn't actually do anything significant yet - it just logs the request. I can post the code if anyone things it's relevant, but I really don't think it's being called at all. (In particular, for normal exceptions I get a custom error page and logging... here I'm just getting the vanilla IIS 404.)
Here's the relevant bit of the web.config file:
<system.web>
<httpHandlers>
<add verb="GET,POST" path="*.robot" validate="false"
type="CSharpInDepth.Wave.RobotHandler, CSharpInDepth"/>
</httpHandlers>
</system.web>
(Obviously there's other stuff in that section too, but I don't think it's relevant.)
Locally, running under the dev server, it works fine. On my real box, I always get a 404. Everything under the web site directory itself is the same (replicated via svn). That includes the bin directory containing CSharpInDepth.dll, which I've verified contains CSharpInDepth.Wave.RobotHandler.
I try to fetch http://csharpindepth.com/foo.robot and just get a 404.
I've tried with and without the assembly name, specific URLs or wildcarded ones... nothing's working.
I'm sure I've just missed some simple flag somewhere in the IIS configuration, but I'm blowed if I can find it...
EDIT: It's IIS version 6. Attempting to add *.robot to the ISAPI filter now...
Well if the hosting box is IIS7 in integrated pipeline you need to add it into the other bit of the config:
<system.webmodules>
....
<modules>
<add name="RobotHandler" type="CSharpInDepth.Wave.RobotHandler, CSharpInDepth"/>
</modules>
....
</system.webmodules>
If it's IIS6 then you'll need to map *.robots to the ASP.NET ISAPI DLL.
(For the non-Skeets you do this as follows)
Open up IIS admin.
Right click on
the Web site you want to configure
and select Properties form the
context menu. This will display the
Web Site Properties dialog.
Select
the Home Directory tab and click the
Configuration button. This will
display the Application
Configuration dialog box.
Click
Add.
Select the aspnet_isapi.dll
from the .NET framework directory,
the extension you want mapped and
either All Verbs, or just the ones
you want to map.
Click ok.
Jon,
You'll have to configure the IIS script mappings to pass *.robot to aspnet_isapi.dll.

Understanding the ASP.NET application folders

The application folders in ASP.NET are used for storing various elements critical to running a website. I want to get a handle on understanding these folders in more depth, specifically the folder accessibility. According to the article on ASP.NET Web Site Layout:
The content of application folders,
except for the App_Themes folder, is
not served in response to Web
requests, but it can be accessed from
application code.
Any browser request to these folders results in a "404 - Page Not Found."
So what prevents folders like App_Code, App_Data, App_WebReferences, bin, etc. from being served to users? Is it an IIS hard coded "don't serve this folder?" Is it a permissions configuration? And is there anyway to knowingly/unknowingly circumvent this?
On my IIS7.5 config, found at C:\Windows\System32\inetsrv\config\applicationHost.config there is this section:
<hiddenSegments applyToWebDAV="true">
<add segment="web.config" />
<add segment="bin" />
<add segment="App_code" />
<add segment="App_GlobalResources" />
<add segment="App_LocalResources" />
<add segment="App_WebReferences" />
<add segment="App_Data" />
<add segment="App_Browsers" />
</hiddenSegments>
See also IIS Documentation.
In IIS7 on Windows Server 2008, ASP.NET is more tightly integrated into the entire processing pipeline, so I would imagine that in IIS7, it is very easy for ASP.NET to say "No, I'm not going to touch that."
In IIS6, IIS itself has very little direct knowledge of IIS, instead, it's all controlled through the ISAPI configuration.
In the IIS6 IIS Manager, right click a website, get Properties, go to the Home Directory tab, and then click Configuration in the lower right. This shows the ISAPI application extensions and what is done for each one.
For all the ASP.NET extensions (aspx, ascx, config, browser, a ton of others) it specifies handling to be done by C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
The ASP.NET system then has registered handlers for each of these file types defined in the global machine.config and/or web.config files at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG
For instance, in the global web.config file, under httpHandlers element:
<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>
So it is not just these special folders, but many types of files, but many types of reserved files that are disallowed from browsing.
The .net framework itself intercepts requests to these folders (along with a bunch of other file types that you should be allowed to browse) and returns a 404 to IIS, which then gets passed back to the browser as "404 - Page Not Found".
So it doesn't happen at the permissions level, or even the IIS level. It's inside the framework -- probably in one of the HttpHandlers in the global web.config.
If you look in there, you can see a ton of file extensions that are explicitly configured to not be served. Presumably you could tweak the settings and cause it to serve, say, web.config files as xml (which is different than the usual behavior of saying that this file type is not served).
It's worth noting that I don't specifically see any of the special folders (app_code, etc) mentioned in the global web.config file. Maybe it's handled inside other HttpHandlers -- for instance, the handler for .aspx might contain some code that prevents serving of .aspx files located in special folders, etc.

Resources