httpModule for 404 - asp.net

I've created an httpModule to handle URL remappings, and it works great on my test system. A request for www.mydomain.com/Some_Fancy_URL gets rewritten to www.mydomain.com/some.aspx?fancy=23 and so on.
When I deploy to the actual web site, I'm getting the default IIS 404 page though.
After doing some research online, it would seem that I need to setup "Wildcard Mapping" in IIS 6 to get the request past IIS and in to my httpModule. The problem is that the site is hosted on a shared server, so it may not be possible to get the ISP to make that change.
My question is, can't I use an httpHandler to tell IIS how I want these requests handled? For example:
<httpHandlers>
<add path="*.aspx" verb="GET,POST" type="System.Web.UI.PageHandlerFactory" validate="false"/>
</httpHandlers>
It would seem like adding this to my Web.Config should tell IIS to stop validating the existence of .aspx files, and just pass the request along for me to process. It doesn't work though.
Any suggestions?

The problem with IIS 6 and ASP.NET is that they're aren't integrated. IIS needs to be told about ASP.NET via script mappings (.aspx, .asmx, wildcard and so on).
None of your web.config configuration settings will influence IIS because web.config is there to configure ASP.NET's behaviour, not IIS. IIS has no knowledge of web.config.
Unless you can hand off a request to the ASP.NET pipeline (via a script map) nothing will happen and all your web.config settings will be ignored.
With IIS 7 the story is quite different. In IIS7, ASP.NET and IIS are closely integrated and share the same pipeline thus permitting you to achieve the result you're looking for.
The alternative may be to find out if your hoster runs a URL rewriter such as ISAPI_Rewrite on their servers. That way you could rewrite urls without having to map a wildcard scriptmap to IIS6.

Through some trial and error, along with more web searches, I found a solution. It essentially parallels Kev's answer.
IIS won't treat a request as .NET unless it has a known file extension (.aspx, .ascx, etc.). When I send along something like www.mydomain.com/anything it looks for a file or folder named "anything", and when it doesn't find one, it just drops off to the default IIS 404 handler.
That's where I took over. I changed IIS 6 to forward 404 problems to /404.aspx. I then created that page with a generic "Your file wasn't found" message in the same style as my web site.
Here's the good part: Now that IIS is sending 404's to a .NET page, the custom httpModule I created is getting fired. The request is for 404.aspx, but IIS is nice enough to also append the original URL as well. You get something like:
www.mydomain.com/404.aspx?404;http://www.mydomain.com/anything
This allows me to parse the request in the httpModule, and rewrite as needed!

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.

web.config urlmapping

I have a comment form on my website on contact.aspx. I want to be able to put up a redirect from /comment (no extension) to point to contact.aspx.
I set up the following url mapping in my web.config and when I test locally it works fine. When I post it to production, the redirect doesn't happen and I get the IIS 404 error.
<system.web>
<urlMappings enabled="true">
<add
url="~/comment"
mappedUrl="~/contact.aspx"/>
</urlMappings>
I'm assuming this is because IIS isn't serving up the request to the asp.net engine and I'm using a shared hosting environment (discountasp.net) so I don't have direct control over IIS to configure it there. I can always put in the subfolder and a default.aspx that will redirect for me, but I thought I would inquire about this route first.
What does the collective think?
Ask your web host if they can configure your virtual directory to serve all requests through ASP.Net.
Many hosts (mine included) are willing to do this. (Mention ASP.Net MVC, which requires this)

UrlRewriting.Net Module + IIS7 Equals Page.User == null?

I've used the UrlRewriting.Net module for a couple years now without any problems in Windows XP and Windows 2003. I just recently upgraded my home PC to Windows 7 and started developing a new website.
The plan was to use .html extensions and rewrite them to their .aspx counterparts using the UrlRewriting.Net module. Everything works flawlessly in VWD 2008, but when I try running it through IIS7 it is a different story.
When I try to access a page via the .html rewrite I can no longer access Page.User; it keeps returning null. If I hit the page using it's .aspx extension, Page.User is correctly populated. I should also mention that I have a LoginView controller in my Master Page and it suffers from the same symptoms: When accessing via .html extension it shows the AnonyousTemplate; When using .aspx extension it properly shows the LoggedInTemplate. I'm guessing the two are related.
[Note: I've also tried extensionless URLs and they exhibit the same problem]
The only way I've gotten it to work is to switch the application pool to Classic, which then requires me to add an ASP.Net ddl handler for the .html extension [otherwise it is handled by the StaticFileHandler and comes up as a 404 error]. However, I'd like my web app to run properly for people without having to fiddle around with IIS.
So I am left with several questions:
Does anyone have ideas as to why Page.User always equals null for .html => .aspx rewritten pages?
Why does it work in VWD 2008, but not IIS7?
What changed from IIS6 => IIS7 that could have caused this?
Any other thoughts on workarounds?
[Note: I just tried a .aspx => .aspx rewrite and it did not exhibit the problem. Not really what I want, but thought I should mention it.]
Just had a breakthrough with the UrlRewriting.Net module. This makes it work in Integrated Mode in IIS7:
<modules runAllManagedModulesForAllRequests="true">
After figuring it out I did a search on "runAllManagedModulesForAllRequests" and the first thing that popped up was Scott Guthrie's blog which actually talks about using it for this purpose.
Another approach that seems to work is to remove the Session module and readd it leaving the "Invoke only for requests to ASP.NET applications or managed handlers" checkbox unchecked. It looks like this in the web.config file:
<system.webServer>
<modules>
<remove name="Session" />
<add name="SessionManualAdd" type="System.Web.SessionState.SessionStateModule, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
</system.webServer>
It seems the problem is that the Session module doesn't execute for say '*.htm' files when HttpContext.RewritePath is used, but removing and readding the module in this fashion causes the Session handler to be executed for the request.
This solution was suggested on the thread below. Unfortunately Microsoft chose not to explain the reasoning behind this behavior fully:
http://connect.microsoft.com/VisualStudio/feedback/details/357248/context-rewritepath-disables-session-module-in-iis7
Microsoft included a fix for this issue (at least for extensionless urls) in Service Pack 1 for Win7 and Windows Server 2008 R2:
http://www.microsoft.com/download/en/details.aspx?id=5842
Also available as a hotfix: http://support.microsoft.com/kb/980368
After this patch is applied, ASP.NET 4 applications can handle requests for extensionless URLs. Therefore, managed HttpModules that run prior to handler execution will run. In some cases, the HttpModules can return errors for extensionless URLs. For example, an HttpModule that was written to expect only .aspx requests may now return errors when it tries to access the HttpContext.Session property.
After applying SP1 or the hotfix, no web.config changes are needed to make the session and forms auth work for extensionless URLs rewritten to asp.net pages/handlers/etc.
I don't know if this fixes anything for rewrites to static file extensions like .htm. My guess is, probably not. I would try to avoid setting runAllManagedModulesForAllRequests="true" in production environments, because it adds unnecessary overhead on static file requests.

HttpModule URL rewriting using IIS6 with no extensionless URLs

We are using the Intelligencia URLRewriting module for asp.net with version 2.0 of the framework and IIS6. Our URLs typically have no extension.
I understand that IIS6 cannot really deal with this situation without a blanket wildcard (which causes other problems).
However, it works! Sometimes. At other times (e.g. on one dev's machine, and on my machine when I point a different virtual directory at the app) it doesn't. By "it doesn't work" I mean the configured HttpModules never even get hit.
Can anyone explain this?
Thanks.
So it turns out what was happening was the following:
request comes in to (say) http://website/products/productid
IIS can't find this hence we get a 404
by chance we have a custom error page set up in IIS for 404s
this error page sticks the referring URL on the end of the 404 error.aspx page
so we get a redirect coming into asp.net along the lines of:
http://website/error.aspx?404;http://website/products/productid
our URLRewriting regexes were now set up in such a way that they discarded the error.aspx bit and dealt with http://website/products/productid as if it were the actual URL
so asp.net renders http://website/product.aspx?id=productid as requested!
I guess this could prove to be a useful kludge for someone, but we're moving to an isapi filter. One heads-up is that this will by default lead to a tight loop of redirects!
If you run a site using the Visual Studio development web server all requests will be handled by asp.net so your HttpModule will run.
On IIS6 this should not happen unless it is set up to forward the requests to asp.net.
Are you sure that when "it works" you aren't running under the Cassini development web server included in VS.NET ? Because extensionless wildcards do work under Cassini, which can be very confusing to say the least.
If you are using an IIS6 with ASP.net 4.0, you must specify and register the modules like this:
<system.web>
<httpModules>
<add name="UrlRewriter" type="Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter"/>
not
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRewriter" type="Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter"/>
</modules>

IIS Wildcard Mapping not working for ASP.NET

I've set up wildcard mapping on IIS 6, by adding "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll", and ensured "Verify that file exists" is not checked :
on the "websites" directory in IIS
on the website
However, after a iisreset, when I go to http://myserver/something.gif, I still get IIS 404 error, not asp.net one.
Is there something I missed ?
Precisions:
this is not for using ASP.NET MVC
i'd rather not use iis 404 custom error pages, as I have a httpmodule for logging errors (this is a low traffic internal site, so wildcard mapping performance penalty is not a problem ;))
You need to add an HTTP Handler in your web config for gif files:
<system.web>
<httpHandlers>
<add path="*.gif" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="true"/>
</httpHandlers>
</system.web>
That forces .Net to handle the file, then you'll get the .Net error.
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /test.gif
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433
You can try use custom errors to do this.
Go into Custom Errors in you Website properties and set the 404 to point to a URL in your site. Like /404.aspx is that exists.
With aspnet_isapi, you want to use a HttpModule to handle your wildcards.
like http://urlrewriter.net/
You can't use wilcard mapping without using ASP.net Routing or URLrewriting or some url mapping mechanism.
If you want to do 404, you have to configure it in web.config -> Custom errors.
Then you can redirect to other pages if you want.
New in 3.5 SP1, you set the RedirectMode to "responseRewrite" to avoid a redirect to a custom error page and leave the URL in the browser untouched.
Other way to do it, will be catching the error in global.aspx, and redirecting. Please comment on the answer if you need further instructions.

Resources