ASP.NET routing in production evironment - iis-7

I have registered a custom asp.net route in a RouteTable.Routes.
routes.MapPageRoute(
"View Service",
"home/services/{*ServiceName}",
"~/home/displayservice.aspx"
);
My application uses ASP.NET 4.0 routing system, and everything works fine on a development machine, when I run the web site from Visual Studio to debug.
When I move the site to IIS7, the routing isn't happening when navigating to
http://new.komplus.ua/home/services/viruses/antivirus/
or any other path that supposed to be handled by the routing system. As a result, I get 404 error from the server.
I am sure I have copied the global.asax and the /home/displayservice.aspx to the web server, and have restarted the web site and app pool since update, but the routing still doesn't take place.
Other, non-routed pages, load fine.
Is there any particular configuration to IIS that has to be done in order for ASP.NET 4 routing to work, in comparison to VS2010 debug environment?

In order for ASP.NET 4.0 routing to work in IIS7 it is requried that the web.config has the webServer element decleared. For examle:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>
It is not a requirement in Visual Studio environment, where routing takes place even without this directive in web.config.

Related

Global.asax Application_BeginRequest not firing unless physical file exists - 404

I use URL rewriting (HttpContext.Current.RewritePath(...)) inside Global.asax so the physical files mostly don't exist.
Everything was working fine until I had to remove site from IIS (8.5) and add it again.
And now I get 404 not found for every request. Example http://localhost/site/article123
And Global.asax Application_BeginRequest event not even firing.
If I however will add empty default.aspx file in folder /site/article123 everything starts to work fine with URL being correctly rewritten.
Files have not changed, so it's ought to be the problem with IIS configuration.
I do have following inside web.config:
<modules runAllManagedModulesForAllRequests="true">
Project in IIS is set as an Application with Application Pool .NET v2.0 Classic
Edit:
Same story in IIS 8.0
The problem was in Managed Pipeline Mode set as classic. Switching from classic to integrated by changing Application pool from .NET v2.0 Classic to .NET v2.0 sorted the problem.
As I understood this: in classic mode IIS is managing requests, while in intergated mode incoming IIS requests map to the ASP.NET engine.
More on pipeline modes: What is the difference between 'classic' and 'integrated' pipeline mode in IIS7?
You need to have ReWrite Module installed under IIS 8.5
Use Web Installer Platform to install it.

httpModules URL rewriter works on Visual Studios Dev Server, but not on IIS 7.5

In my web.config, I have a custom Url rewriter class that takes query strings such as /movies/godzilla.aspx and turns it into /template.aspx?id=1234
The rewriter works fine when I run it locally on the built in web server in Visual Studios, but when I put it on IIS 7.5 and try to access the page using the friendly name, I get a message saying the connection was reset and have to do an iisreset to get the site back online. The page is perfectly accessible from the server using the query string URL.
Here is a snippet of my web.config:
<system.web>
<httpModules>
<add name="ApFriendlyURL" type="FriendlyURL" />
</httpModules>
....
</system.web>
I'm confused as to why this works when running on the Dev Server in Visual Studios but not on IIS. I've played around with the settings in IIS, but I can't seem to find anything that would let me use the FriendlyURL class as the rewriter
HTTP modules in IIS 7.5 have to be configured in the system.webServer/modules section. Just copy your module definition there.
http://msdn.microsoft.com/en-us/library/aa347531(VS.90).aspx
Please be aware of the possible problem with the duplicate module configuration. If this is so, you turn off the integrated mode configuration:
http://www.iis.net/ConfigReference/system.webServer/validation
If you are working on .NET 2.0 application you should enable "Integrated mode" in your AppPool setings.

Windows Authentication not working for classic ASP pages (but does work for ASP.Net pages w/in same site)

We have an IIS7 intranet site running under integrated pipeline that is mostly ASP.Net with a few legacy classic ASP pages. The site allows anonymous access to most areas, but uses Windows Authentication to protect certain folders. Requests to ASP.Net pages in the protected folders behave as expected (authorized users can see them, others are denied), but any user can see any classic ASP page in the protected folders, regardless of permissions.
I suspect the windows authentication module is not being invoked for requests to classic ASP pages. We're running in integrated pipeline mode, and I found this article (http://learn.iis.net/page.aspx/244/how-to-take-advantage-of-the-iis7-integrated-pipeline/) which indicates that you need to explicitly remove and re-add modules if you want to take advantage of the integrated pipeline for non-ASP.Net requests. I tried to copy the article's example only replacing FormsAuthenticationModule with WindowsAuthenticationModule by adding the following to the web.config at the application root:
<system.webServer>
<modules>
<remove name="WindowsAuthentication" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="" />
</modules>
</system.webServer>
However, classic ASP pages are still being served regardless of permission.
Classic ASP pages totally ignore web.config or any .config actually.
The only way to handle this for classic ASP is through IIS, you will have to move the classic ASP pages to be under separate virtual website then for that virtual website set Windows Authentication and disable Anonymous Access.
This might help you as well:
IIS7: Setup Integrated Windows Authentication like in IIS6

Getting 404.0 error for ASP.NET MVC 3 app on IIS 7.0 / Windows Server 2008

I am attempting to deploy an ASP.NET MVC 3 application to a Windows 2008 x64 server (running IIS 7.0 obviously), and IIS does not want to seem to serve up the content properly. All requests are resulting in a 404.0 error, because the requests are not matching any handler and IIS is attempting to use the StaticFile handler to serve up the requests. The issue seems to be related to .NET 4.0, as I have an MVC 2 application running just fine in an app pool that is configured for the .NET 2.0 runtime.
I have had no issues deploying this same application to IIS 7.5 servers both on Windows 7 and Windows Server 2008 R2.
Prior to deployment, the 2008 server did not have .NET 4.0 or ASP.NET MVC 3 installed, so here are the steps I undertook prior to deploying the application:
Installed .NET 4.0
Ran aspnet_regiis.exe (from the Framework64/v4.0.30319 folder)
Installed ASP.NET MVC 3 using the web platform installer
Applied MS update KB980368 to enable certain IIS 7.0 or IIS 7.5 handlers to handle requests whose URLs do not end with a period
Requests to static resources in the application (JavaScript files, images, etc) go through without a hitch, but any request to an MVC action fails with a 404.0 error. I have noticed that IIS is using the StaticFile handler to handle these requests, which is obviously incorrect. The ASP.NET 4.0 handlers (i.e. ExtensionlessUrl-ISAPI-4.0* handlers) are properly defined as far as I can tell, so I have no idea why/how the request would not be handled by one of these handlers and would fall all the way down to the StaticFile handler.
I also came across the following MS knowledge base article which mentions that you should ensure HTTP Redirection and Static Content Compression are enabled/installed on the server where you are experiencing the 404 errors. I checked, and both features were already enabled for my server. I even tried removing and reinstalling the features to no avail.
At this point I am completely out of ideas for why this is not working properly. I have been able to replicate the issue on 2 different IIS 7.0 servers. What am I missing?
You actually just reminded me that I needed to fix this issue in an enviroment here. If your situation is the same as mine then it's a simple fix.
Just add the following to your web config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
Edit: To provide further explanation on the issue at hand. In my case what was happening was when I added custom route mappings IIS was seeing the requests as Folder/Static File requests and thus was skipping over the ASP.NET worker process. This behaves differently under development environment generally because it is being run under the development web server which will also pass all requests through the .net process.
This Web Config entry tells IIS that you have modules that should be run on every web request even if IIS determines it to be a static file or a folder.
Please make sure that you are running under IIS 7.0 Integrated mode. If you need to run it under IIS 7.0 Classic mode, you need to perform several actions to make the routes work. Please refer the following blog posts;
http://www.tugberkugurlu.com/archive/running-asp-net-mvc-under-iis-6-0-and-iis-7-0-classic-mode---solution-to-routing-problem
http://www.tugberkugurlu.com/archive/deployment-of-asp-net-mvc-3-rc-2-application-on-a-shared-hosting-environment-without-begging-the-hosting-company
The issue ended up being that my code was completely relying on the auto-start functionality that is available only in IIS 7.5. I was able to discover the issue with the help of the Failed Request Tracing feature in IIS, and I have now modified my global.asax.cs file so that the application will be properly initialized, regardless of how/when it is loaded.
My solution, after trying EVERYTHING:
Bad deployment, an old PrecompiledApp.config was hanging around my deploy location, and making everything not work.
My final settings that worked:
IIS 7.5, Win2k8r2 x64,
Integrated mode application pool
Nothing changes in the web.config - this means no special handlers for routing. Here's my snapshot of the sections a lot of other posts reference. I'm using FluorineFX, so I do have that handler added, but I did not need any others:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="None"/>
<pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
<httpRuntime requestPathInvalidCharacters=""/>
<httpModules>
<add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx"/>
</httpModules>
</system.web>
<system.webServer>
<!-- Modules for IIS 7.0 Integrated mode -->
<modules>
<add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx" />
</modules>
<!-- Disable detection of IIS 6.0 / Classic mode ASP.NET configuration -->
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
Global.ashx: (only method of any note)
void Application_Start(object sender, EventArgs e) {
// Register routes...
System.Web.Routing.Route echoRoute = new System.Web.Routing.Route(
"{*message}",
//the default value for the message
new System.Web.Routing.RouteValueDictionary() { { "message", "" } },
//any regular expression restrictions (i.e. #"[^\d].{4,}" means "does not start with number, at least 4 chars
new System.Web.Routing.RouteValueDictionary() { { "message", #"[^\d].{4,}" } },
new TestRoute.Handlers.PassthroughRouteHandler()
);
System.Web.Routing.RouteTable.Routes.Add(echoRoute);
}
PassthroughRouteHandler.cs - this achieved an automatic conversion from http://andrew.arace.info/stackoverflow to http://andrew.arace.info/#stackoverflow which would then be handled by the default.aspx:
public class PassthroughRouteHandler : IRouteHandler {
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
HttpContext.Current.Items["IncomingMessage"] = requestContext.RouteData.Values["message"];
requestContext.HttpContext.Response.Redirect("#" + HttpContext.Current.Items["IncomingMessage"], true);
return null;
}
}
If you are running your web application on IIS 7.5 or above, please ensure that the role services for IIS are enabled properly. The role services of interest are : ASP.NET, Basic Authentication, HTTP Redirection, ISAPI filters, etc.
You could go to the role services via Add or Remove programs - Turn Windows features on or off.
Hope this helps.
Regards,
Kiran Banda
I had the same problem. Mine ended up being a failed assembly upon the app starting. I enabled the Fusion Log Viewer to see which assemblies were failing and figured it out. I would have never discovered this since it seemed like an MVC routing issue, but I figured I would post this incase anyone else wasted hours on this problem as well!

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.

Resources