1

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?

George Mauer
  • 117,483
  • 131
  • 382
  • 612

1 Answers1

1

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.

Community
  • 1
  • 1
welegan
  • 3,013
  • 3
  • 15
  • 20
  • No ops team. The thing that I mentioned happens out of the box with a fresh Windows+VS install and iisexpress. Nothing out of the ordinary at all in the web.config and no mention of any specific paths. If something is getting configured by default on the machine.config level I don't know what it can be since you can serve content from arbitrarily named directories (plus I've never seen anything like that in machine.config). I fully understand how OWIN and self-host stuff handles this, there is no mystery there, but the IIS pipeline is kinda a question mark to me. – George Mauer Nov 12 '14 at 20:15
  • 1
    I see, I misread the original question since it's not about how controllers get served so much as why the `*.cs` files don't get served as static content. That is most definitely handled by the info from this answer: http://serverfault.com/questions/175499/serving-cs-csproj-files-on-iis7-5 and looking for `fileExtension` in machine.config will probably point you at the right lines. – welegan Nov 12 '14 at 20:38
  • I see. So you're saying it's file extension based rather than folder based? So basically there's something magic about a `.` in the route that's built into IIS? Also, not sure where cs and other files are configured. Nothing special in my web.config and `ls C:\Windows\Microsoft.NET\Framework\ -rec -inc machine.config | Get-Content | Select-String -Pattern fileExten` gives me nothing. – George Mauer Nov 12 '14 at 21:12
  • try `ls C:\Windows\Microsoft.NET\Framework\ -rec -inc machine.config | Get-Content | Select-String -Pattern .cs`, I wouldn't really call it magic since most of the files on your system have a `.` character in them and the point of this is to not serve certain files that are in a website folder. – welegan Nov 12 '14 at 21:42
  • That will find anything with `cs` since the arg to `-Pattern` is a regex. Instead `ls C:\Windows\Microsoft.NET\Framework\ -rec -inc machine.config | Get-Content | Select-String -Pattern '\.cs'` still turns up nothing. As for files having `.`s in them yes, they often do, but this isn't about files, its about `routes` and routes can perfectly legally contain the `.` character as far as I know so I'm still not sure what specifically the rule is. – George Mauer Nov 12 '14 at 21:50
  • Good to know about the -Pattern flag. I realized that iis express does not have the same config setup as standard iis, refer to this answer for the path: http://stackoverflow.com/questions/12946476/where-is-the-iis-express-configuration-metabase-file-found try running the command on that path instead. As for route v file, it's true that routes can be anything and take precedence, but your question is about why static files are not served from the controller folder. In that case, file path ~= route hence file extension applies to route, that was my only point. – welegan Nov 13 '14 at 17:31
  • Aha, good call on iisexpress not using machine.config - yes the right `fileExtnexion` keys are in the applicatiohost.config. I appreciate you staying with this as I try to clarify. Are you saying that when a route is requested, IIS first checks if a mapped file exists on the file system, if its allowed it serves it, otherwise it calls into asp.net? – George Mauer Nov 13 '14 at 18:49
  • Yep, that's exactly it. Although keep in mind, that after it "calls into asp.net" it runs through the handler / module mappings I talked about in the original answer, so there's other config tags that come into play afterwards. – welegan Nov 13 '14 at 22:10
  • I see, can you edit that into your answer so that I can accept it? – George Mauer Nov 13 '14 at 23:13
  • I would say that things get a lot clearer with self hosting, not muddied :) – George Mauer Nov 13 '14 at 23:34
  • Sorry, I've grown up on the IIS pipeline so it's what I'm more familiar with :) the muddy comment stays :-P – welegan Nov 14 '14 at 19:44