How is the order of execution for HttpModules determined? - asp.net

Suppose that both FirstModule and SecondModule handle the Application_BeginRequest event. Will it execute in the order defined in the web.config?
<httpModules>
<add type="MyApp.FirstModule, MyApp" name="FirstModule"/>
<add type="MyApp.SecondModule, MyApp" name="SecondModule"/>
<add type="OtherApp.OtherModule, OtherApp" name="OtherModule"/>
</httpModules>
Are there other ways that the order can be specified?

According to this forum post, HttpModules are executed in the order in which they were registered. This makes sense to me, because otherwise the <clear> and <remove> directives would also not work as expected, e.g. when used like this:
<httpModules>
<clear/>
<add... />
</httpModules>

According to the Internet Information Services (IIS) 7.0 Resource Kit book extract from Microsoft Press,
To resolve such relative ordering dependencies, the administrator can control the relative ordering of modules by changing the order in which they are listed in the modules section.
This works because the server uses the order in the modules configuration section to order module execution within each request processing stage. By placing module A before module B in the list, you can allow module A to execute before module B.

Related

Why are Content, Scripts served as static and other directories not?

So this is a bit of asp.net I feel like way too many people don't understand. That is to say, I don't understand it and I've asked a bunch of people/googled and no one else seems to know the specifics either.
By default ASP.Net applications will serve files in Content and Scripts directories as static content. In fact, if I create other directories, I think it will serve static content in these as well.
However, the contents of some directories won't be served - the typical Asp.Net Mvc Controllers directory for example. In addition, you can always configure routes in asp.net (or OWIN handlers) that will pick up certain routes but not either.
Nothing seems to be configured anywhere. I have my suspicions, but I'm really not clear on what exactly is the rule for what gets served as static content and what gets processed by asp.net?
I've always found this graphic helpful: https://web.archive.org/web/20211021221111/https://www.4guysfromrolla.com/images/step2.gif
Specifically, the HttpHandlers mentioned in that graphic correspond to this section of the Web.Config file in your .NET web project's root directory:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
The path attribute of that tag can be used to configure only certain directories being handled by a certain class. At that point, IIS will hand off the HTTP request to the appropriate class, with the proper context and thread etc. My guess is that if you are running IIS with multiple frameworks, each has a distinct path associated with its add-handler tag.
Additionally, IIS has its own default settings for what file extensions are mapped to what handler classes. These can also be modified in the IIS management interface, so it's possible that your super-helpful ops team added that for you there even if it's missing from your web.config. At the end of the day, though, it's a relationship between url-HttpHandler class that determines static-file versus dynamic.
Edit:
There's another set of tags, outlined at this ServerFault answer:
https://serverfault.com/questions/175499/serving-cs-csproj-files-on-iis7-5
That describes a <add fileExtension=".cs" allowed="false" /> tag that operates on the file extension as opposed to a pattern on the entire path. This is what disallows files ending in .cs, and .csproj from being served. Additionally, since you're operating on an installation of IISExpress, you should know that it uses a different configuration file than the standard machine.config. The path for that file is described at this answer:
Where is the IIS Express configuration / metabase file found?
All this gets muddied a little by the notion of self-hosting, aka no IIS. Nancy does this, I believe, and ServiceStack can as well. I have no experience doing that, but the way they handle paths is probably a little different.

Custom HttpHandler never running

Forgive me if this is basic. I've never made one before and can't seem to figure out why it's not working. I wrote a little handler to do some parsing on CSS files. I added this:
<system.web>
<httpHandlers>
<remove verb="*" path="*.css"/>
<add verb="*" path="*.css"
type="MyNameSpace.CssRelativePathHandler,CssRelativePathHandler" />
</httpHandlers>
</system.web>
Nothing ever happens. CSS files get parsed normally. No errors, nothing, the code never runs. What am I missing? Shouldn't this cause the handler to be used when *.css files are served? (I added the "remove" later, since I thought perhaps I needed to do that to override a built-in hander, again, no difference either way).
This is IIS 6. I added the IIS 7 code anyway (after searching for answers) but makes no difference.
<system.webServer>
<handlers>
<add name="CssHandler" verb="*" path="*.css"
type="MyNameSpace.CssRelativePathHandler,CssRelativePathHandler" />
</handlers>
</system.webServer>
You need to configure IIS6 to send requests for .css files to ASP.Net.
Had you been using IIS7, your <system.webServer> element would have done that for you, but IIS6 predates this.
For IIS 6 you need to have to tell it to send *.css files to ASP.NET.
Launch IIS Manager
Right-click on Default Web Site
Click on the Home Directory tab
Under Application Settings click on Configuration...
Add a new association for .css and map it to .NET executable:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
It sounds like you need to configure IIS to enable ASP.NET to execute the .css extension.
Phil Haack has a walkthrough on doing that (just replace .mvc with .css under the heading "Mapping .mvc to ASP.NET"):
http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
Or you can set up a wildcard mapping in IIS 6:
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/5c5ae5e0-f4f9-44b0-a743-f4c3a5ff68ec.mspx?mfr=true
I'd recommend going with the first method as doing the wildcard approach will send all requests to ASP.NET - so it has a more overhead.
PS: Further down Phil's post, he also lists "IIS6 Extension-less URL" and also covers the wildcard mapping method.

Nested ASP.NET 'application' within IIS inheriting parent config values?

I currently have 2 x ASP.NET 3.5 web applications in IIS7 (lets call them WebParent and WebChild).
WebChild is nested within the WebParent listing in IIS7 and is set up as an application (rather than just a virtual directory within WebParent). Both currently use their own (Classic) application pool.
Both WebParent and WebChild have their own fully defined web.config files in their own root directories.
I had assumed that seeing as WebChild is defined as an 'Application' within IIS, that it would not inherit anything from the WebParent configuration file. However, despite this configuration, I am seeing errors related to various elements within the web.config already being defined (which is correct, there are a couple items that are in both config files, but I thought they should be treated completely independently from one another)?
Can anyone please clarify why this might be occurring?
The exact solution to your problem will depend on what configuration exception message you are seeing. However, this is a typical problem that can often be solved through use of the inheritInChildApplications attribute on the location element in the web.config for "WebParent". By wrapping the entire system.web section in a location element as follows, you should be able to eliminate the problem you described:
<location path="." inheritInChildApplications="false">
<system.web>
<!-- ... -->
</system.web>
</location>
With IIS 7, you will also want to wrap the system.WebServer section the same way:
<location path="." inheritInChildApplications="false">
<system.webServer>
<!-- ... -->
</system.webServer>
</location>
This solution is based on an excellent blog article that I found here.
If they are repeated, you'll have to <remove/> then in the child application web.config first, then add back the element you'd like it it's place. This is assuming that you'd like to have a different value. If you don't, then just omit the element. A connection string would be a good example of something that is likely common for all applications - so you only need to specify it in the root.
Example:
<siteMap defaultProvider="AdminSiteMapProvider" enabled="true">
<providers>
<remove name="AdminSiteMapProvider"/>
<add name="AdminSiteMapProvider" description="Admin SiteMap provider" type="System.Web.XmlSiteMapProvider" siteMapFile="~/App_Data/admin.sitemap" securityTrimmingEnabled="true" />
</providers>
</siteMap>
I think the inheritInChildApplications="false" is good for cases where you still want to inherit some part of the configuration from the parent.
In cases where you want to completely stop inheritance (as in this case if I'm correct), I'd suggest to use 2 separate application pools for the 2 apps and then apply a not very well documented setting in the applicationHost.config file as I explained in this question “Entry has already been added” - Two Separate App Pools
<add name="MyAppPool" autoStart="true" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" enableConfigurationOverride="false">
<processModel identityType="NetworkService" />
</add>
Follow Scott's advise and also ensure that you have right clicked WebChild in IIS and selected Convert to Application.

ASP.NET 3.5 application with multiple web.config files (IIS 7)

We are working on a web application that creates more web applications.
Each web application will have to get a Url Rewrite rule (URL REWRITE MODULE 2.0).
As far as I know, there's no way to add such rules without modifying the web.config file (am I right??).
So my plan was to work with multiple web.config partial files. One main .config file, and lots of .config files per application (every file will contain it's web application url rewrite rules).
This way sounds a little bit messy, but I can't think of anything else, and suggestions will be welcomed.
So is it possible to use very-multiple web.config files for the root application?
Thanks in advance, Gal.
This following Tag will do the trick.
The absence of this tag was the main reason for my problem when i using with two web.config files for my two different application running in my website.
**<location path="." inheritInChildApplications="false">**
<system.web>
<!-- ... -->
</system.web>
**</location>**
Every application must have a full web.config and not partial, exept if you go with net 4
The trick is to use a lot the remove command on the other inside web.config and remove the parents setting that must not used on this.
For example if on the main root you have the a module that you do not won to use it on the other trees, you use the remove command on all other web.config to remove it. Especial the modules that are on one Bin and not on an other directory bin.
<httpModules>
<remove name="TheHttoModuleNotNeedHere" />
<remove name="AnonymousIdentification" />
... add here your other modules for that directory...
</httpModules>
The remove command is working for almost all sessions on config.
You can do make it work, I have done it, but its a lot of work to find all the conflicts/unnecessary configs and remove it.
For some other session there also the clear command. For example on role Manager you can clear all and add new.
<roleManager enabled="true" ...>
<providers>
<clear />
<add name="MyName" ... type="System.Web.Security.SqlRoleProvider" />
</providers>
Hope this help as tips to make it work.

Bypass existing HttpModule for a http handler

Scenario:
I have a bunch of web applications for which I want to add a simple ping functionality via http handler. Example: Http://myserver/foo/testfolder/ping.me
Problem:
For some of the applications this approach does not work becasue of custom HttpModule. These modules have some depedency on either authentication or some other processing logic due to which it makes the request invalid.
I am trying to find a solution to get this ping functionality work without making any changes to existing HttpModules.
HttpModules are associated with the application instance and applies to all sub folders.
Hence you cannot bypass it.
Assuming you're wanting to disable HttpModules for only the URL to the ping handler, you can do this in your web.config:
<location path="/url/to/ping/handler">
<system.web>
<httpModules>
<remove name="moduleToRemove1"/>
<remove name="moduleToRemove2"/>
</httpModules>
</system.web>
</location>
This will disable the modules for the given url only.

Resources