Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a wwwroot folder (ASP.NET Core style) in ASP.NET 4.5 project

I quite like the approach of the new asp.net (asp.net 5\core 1.0) web apps with the wwwroot folder being the root and only static files in there being served up.

Is possible through routing or other configuration to have a wwwroot folder in an asp.net 4.5 project behave in a similar way, such that static files are only served out of it, and it's the "root" of the webapp for static files?

(Part of my motivation in asking this is that I have an angular app hosted in an asp.net 5 project in VS2015, but I need to move this into an asp.net 4.5 project, but would like to keep the existing structure on disk)

Attempt using OWIN

I've attempted this using an empty ASP.NET 4.5 web app project and OWIN. So my folder structure has my angular app, with a main index.html file in a wwwroot folder in the project folder. There are no HTML files in the root of the project.

I've added OWIN through nuget and the following startup file:

[assembly: OwinStartup(typeof(MyApp.UI.Startup))] namespace MyApp.UI {     public class Startup     {         public void Configuration(IAppBuilder app)         {             string root = AppDomain.CurrentDomain.BaseDirectory;             var physicalFileSystem = new PhysicalFileSystem(Path.Combine(root, "wwwroot"));             var options = new FileServerOptions             {                 EnableDefaultFiles = true,                 FileSystem = physicalFileSystem             };             options.StaticFileOptions.FileSystem = physicalFileSystem;             options.StaticFileOptions.ServeUnknownFileTypes = false;             options.DefaultFilesOptions.DefaultFileNames = new[] {"index.html"};             app.UseFileServer(options);         }     } } 

This fails though - the source of my index.html file does load when I run this, but all the css, js, etc files that it references fail with a 404. Even worse, if I append gulpfile.js onto the root url it loads my gulp file from the root of the project folder. This is precisely the sort of thing I'm trying to avoid.

Any ideas?

like image 506
mutex Avatar asked Mar 29 '16 20:03

mutex


People also ask

What is the use of Wwwroot folder in ASP.NET Core project?

By default, the wwwroot folder in the ASP.NET Core project is treated as a web root folder. Static files can be stored in any folder under the web root and accessed with a relative path to that root.

How do I add wwwroot to project NET Core?

Adding wwwroot (webroot) folder in ASP.NET Core: In order to add the wwwroot folder, right-click on the project and then select add => new folder option and then provide the folder name as wwwroot.

Where is wwwroot folder in ASP.NET Core?

The path of the wwwroot folder is accessed using the interfaces IHostingEnvironment (. Net Core 2.0) and IWebHostEnvironment (. Net Core 3.0) in ASP.Net Core. The IHostingEnvironment is an interface for .

What file types should be placed in the wwwroot folder?

The wwwroot folder is new in ASP.NET 5 to store all of the static files in your project. Any files including HTML files, CSS files, image files, and JavaScript files which are sent to the user's browser should be stored inside this folder.


2 Answers

I believe I have a working method for doing this now. Took a bit of googling and experimentation, but in the end I came up with the following process:

  1. Create a new ASP.NET 4.5 project in VS2015, selecting the Empty Template

  2. Add OWIN references through nuget (Install-Package Microsoft.Owin.Host.SystemWeb and Microsoft.Owin.StaticFiles)

  3. Add a startup file similar to this:

    [assembly: OwinStartup(typeof(MyApp.Startup))] namespace MyApp.UI {     public class Startup     {         public void Configuration(IAppBuilder app)         {             string root = AppDomain.CurrentDomain.BaseDirectory;             var physicalFileSystem = new PhysicalFileSystem(Path.Combine(root, "wwwroot"));             var options = new FileServerOptions             {                 RequestPath = PathString.Empty,                 EnableDefaultFiles = true,                 FileSystem = physicalFileSystem             };             options.StaticFileOptions.FileSystem = physicalFileSystem;             options.StaticFileOptions.ServeUnknownFileTypes = false;             app.UseFileServer(options);         }     } } 
  4. Add the following to your web.config file, to prevent IIS from serving static files you don't want it to, and force everything through the OWIN pipeline:

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

I'm always open to better suggestions on how to do this, but this at least seems to work for me.

like image 64
mutex Avatar answered Oct 09 '22 04:10

mutex


Although OWIN worked for me in my dev environment running in VS 2017, it didn't work once deployed to azure. We run a SPA as well, and are storing the webpack output in ~/wwwroot/ but wanted it to load as if it was in the project root ~/ just like .net core webapi does it. I accomplished it by using just the URL rewrite shown below:

<system.webServer> <rewrite>   <rules>     <rule name="wwwRootFix" stopProcessing="true">       <match url="(.*)" />       <conditions logicalGrouping="MatchAll">         <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />         <add input="{APPL_PHYSICAL_PATH}wwwroot\{R:1}" matchType="IsFile" />         <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />         <add input="{REQUEST_URI}" pattern="^/(wwwroot)" negate="true" />       </conditions>       <action type="Redirect" url="/wwwroot/{R:1}" />     </rule>     <rule name="React Routes" stopProcessing="true">       <match url=".*" />       <conditions logicalGrouping="MatchAll">         <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />         <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />         <add input="{REQUEST_URI}" pattern="^/(wwwroot)" negate="true" />       </conditions>       <action type="Rewrite" url="/wwwroot/index.html" />     </rule>   </rules> </rewrite> </system.webServer> 

The first rule ensures that the file you are looking for doesn't exist in the root, isn't a folder, is found in the new path, isn't the wwwroot folder, nor is it part of the api. If ALL of those conditions are met, it tries to load the data from wwwroot.

The second rule checks to make sure you aren't trying to load the api, or a file that actually exists at the root. If both conditions are met, it loads the default SPA html document (in our case we use react).

Effectively this allows react-router 4 to handle all other routes after all the other conditions above have failed to find a match, and make it so it doesn't throw a 404 error when trying to load one of the react-router routes.

like image 40
sec0ndHand Avatar answered Oct 09 '22 05:10

sec0ndHand