9

I'm experimenting with keeping my content in non-default locations (eg in bower_components or /packages/../tools). As part of the experiment I am trying to set up an asp.net mvc 5 application where hitting a certain route allows me to browse files in the undersorejs package directory.

I have the following nuget packages (in addition to the default)

Install-Package underscore.js
Install-Package Microsoft.Owin.StaticFiles
Install-Package Microsoft.Owin.Host.SystemWeb

This is what I have in an OWIN startup class

 var fileSystem = new PhysicalFileSystem(
                    HttpContext.Current.Server.MapPath("~")+"/../packages/underscore.js.1.6.0"
                  );
 var options = new FileServerOptions {EnableDirectoryBrowsing = true, FileSystem = fileSystem};

 app.MapWhen(ctx => 
      ctx.Request.Uri.AbsolutePath.StartsWith("/__underscore"), 
      ab => ab.UseFileServer(options)
 );

To my understanding and previous experimentation this is pretty straightforward - when the request begins with /__underscore use the simple static file server. However when I head over to /__underscore I get a 404 error.

However, placing breakpoints I can see that the UseFileServer lambda executes once on startup and then never again, while the predicate lambda is called on every request (and returns the correct value).

What am I missing?

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

1 Answers1

15

You need to specify the RequestPath as well:

var options = new FileServerOptions {
                      EnableDirectoryBrowsing = true,
                      FileSystem = fileSystem,
                      RequestPath = PathString.FromUriComponent("/__underscore")
                      };

As per your comment:

If you're unable to download files, try to explicitly register OwinHttpHandler in your Web.Config:

<system.webServer> 
    <handlers> 
        <add name="Owin" verb="" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb"/> 
    </handlers> 
</system.webServer>

Alternatively, you can set runAllManagedModulesForAllRequests to 'true':

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="FormsAuthenticationModule" />
    </modules>
</system.webServer>
haim770
  • 48,394
  • 7
  • 105
  • 133
  • aha! so secondary question - why did the handlers run in that order? shouldn't the second lambda run whenever the predicate returns true? – George Mauer Jun 08 '14 at 16:39
  • Interesting, it now allows navigation but results in a 404 when I try to download a file – George Mauer Jun 08 '14 at 16:58
  • What's the file extension? – haim770 Jun 08 '14 at 16:58
  • Great, that worked! Any insight into why that handler is necessary? I believe Owin is a huge deal and I'd really would like to understand what's going on with this at as deep a level as possible. – George Mauer Jun 09 '14 at 01:01
  • interesting, I added the `handlers` node above and now any requests to the Content and Scripts directories no longer work. Whats going on?! – George Mauer Jun 09 '14 at 01:10
  • If you'll limit `OwinHandler` to the `__underscore` path you'll be fine (``). Yet, i have to admit that it's still unclear to me too how exactly Owin integrates with IIS pipeline (which is what causes the problems here as hosting the app outside of IIS works great). – haim770 Jun 09 '14 at 06:42
  • 1
    Apparently IIS `StaticFileHandler` is taking over such requests, and when no explicit configuration to run other modules (Owin), it (rightly) aborts the request with 404 as no static file is matching `__underscore/.....`. – haim770 Jun 09 '14 at 07:37