The virtual directory inside the main ASP.NET application in IIS

We have an application using ASP.NET Core 1.0 RC1 and hosted on IIS. It is working fine. Now we have static content that is available in the file sharing and should be accessible from the application.

Prior to ASP.NET 5, we added a virtual directory to IIS and could easily access shared content. Using our ASP.NET 5 application, this unfortunately does not work. We just get 404 back when we try to access static content.

Our application uses app.UseIISPlatformHandler() and app.UseStaticFiles() , but this does not work. We found that we could use app.UseFileServer() with custom FileServerOptions to get the desired behavior, but we are curious if this is also possible with the usual "old" way of adding a virtual directory to IIS.

+16
source share
6 answers

Today I ran into this problem and finally was able to fix it. The trick (for me, probably not for everyone) is that the aspNetCore handler aspNetCore disabled in the sub-application and enabled in the main ASP.NET Core application.

My ASP.NET Core application has a basic Web.config

 <configuration> <system.webServer> <handlers> <add name="aspNetCore" path="*" verb="*" type="" modules="AspNetCoreModule" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" /> </handlers> <aspNetCore processPath="dotnet" arguments=".\bin\Debug\netcoreapp2.0\myapp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" /> </system.webServer> </configuration> 

and the application added as a sub-application in IIS has

 <configuration> <!-- removed --> <system.webServer> <handlers> <remove name="aspNetCore" /> </handlers> </system.webServer> </configuration> 
+16
source

I found a blog that I think was written by the OP.

As a result, we do not use the virtual directory in IIS at all, but map your path in Startup.cs to the directory of the physical server. I hope the OP does not mind that I inserted the blog below, but it helped me when I first encountered this problem today.

Source: https://www.jauernig-it.de/asp-net-coreiis-serving-content-from-a-file-share/

There are situations when you want to provide static content to your application that is not part of it, for example, because it exists in a file share. The content of a website that is managed by a business unit can be such an example of use. In ASP.NET before Core, this was not a problem in IIS: just create a virtual directory on your IIS website and specify it for the file share.

Unfortunately, in ASP.NET Core this approach no longer works. If you add a virtual directory to an ASP.NET Core application in IIS, it is not recognized and returns 404. This is due to DNX / Kestrel, which runs under IIS (using the HttpPlatformHandler module) and to which IIS only mediates requests. Kestrel knows nothing about virtual directories from IIS. And since the main ASP.NET applications are independent of IIS and can also run without it (for example, with Kestrel autonomous work), this should be considered as a good thing.

But now we need a different solution for our problem ... fortunately, ASP.NET Core provides us with a software interface for serving files from anywhere. Just add the following code to your Startup.cs Configure () method:

 app.UseFileServer(new FileServerOptions { FileProvider = new PhysicalFileProvider(@"\\server\path"), RequestPath = new PathString("/MyPath"), EnableDirectoryBrowsing = false }); 

Essentially, this adds the file server to the physical path to the server, which is then available at a specific request path, in this case with the directory scan turned off. You can also serve along the path relative to your application using the new PhysicalFileProvider (env.WebRootPath + "\ path") (this env is of type IHostingEnvironment as the Configure () parameter). Voila, that’s all. There is no need to add a "virtual directory" in IIS, this material is outdated and a thing of the past. This is good for me because we are becoming more independent of all IIS ...

+11
source

Not directly.

You see, the problem is that when you have a .NET-Core application, it runs in Kestrell and not in IIS (for .NET Core <2.2).

Now, to host your .NET-Core application in IIS, AspNetCoreModule launches your .NET-Core application with Kestrell on port X 127.0.0.1, and then redirects traffic from your iis-domain + virtual directory to port X on 127.0.0.1 ( it can use something else besides TCP).

Problem 1 is that Kestrell has rather limited functionality, that is, it does not have virtual directories.
Problem 2 is that IIS, unlike nginx, does not actually perform reverse proxying properly, or we should say “completely”.

IIS can forward domainxy: 80 to 127.0.0.1:random in order. But what he is not doing properly is rewriting domainxy: 80 / foo to 127.0.0.1:random (images, header, json-ajax-results, urls, return-url, cookies, etc. And vice versa). Instead, it rewrites the domain: 80 / foo to 127.0.0.1:random/foo, which is a problem if the server 127.0.0.1:random (Kestrell) does not support virtual directories.

Therefore, if you want to run your application in your virtual directory, you have two options (both include changing your application — if you can)
1) Put all your stuff in the "foo" directory (including the MVC controller route) if your application will be deployed only once.

2) As suggested in https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552, you can configure the application framework to simulate this folder, as in RoR:

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { string virtual_directory = "/Virt_DIR"; // virtual_directory = "/"; if (virtual_directory.EndsWith("/")) virtual_directory = virtual_directory.Substring(0, virtual_directory.Length - 1); if (string.IsNullOrWhiteSpace(virtual_directory)) Configure1(app, env, loggerFactory); // Don't map if you don't have to // (wonder what the framework does or does not do for that case) else app.Map(virtual_directory, delegate(IApplicationBuilder mappedApp) { Configure1(mappedApp, env, loggerFactory); } ); } // Configure is called after ConfigureServices is called. public void Configure1(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { [...] (here comes what used to be in your old Configure method) 

You will need to configure the name of the virtual directory somewhere. Caution, when you have / return URLs in JavaScript / ajax requests, they will not be automatically displayed. You have to do it yourself, but it was the same with the old ASP.NET.

Indeed, like RoR:

Rails.application.config.relative_url_root map || "/" do
run RedmineApp :: Application
end

As for the virtual directory in the application: no, it's not that simple.
IIS is a full-fledged web server that will serve the contents of this mapped directory as it was there (if it can read the contents).

If you redirect the entire parent directory to Kestrell, IIS will not be able to serve the subdirectory, and your application will need to do this. This means that you need to configure a static file server for this particular directory and tell it where the files are located, as you did.

What you could do is tell IIS not to use a proxy for this particular virtual subdirectory (just like you can determine the location of a static file in nginx - except that IIS probably does not support this function).

However, you can create a symbolic link (or mount / junction) in the directory of your application, which goes to a network folder if Windows is capable of it (mklink). Then .NET Core will be able to serve it statically. But actually, it sounds like a hack.

If you cannot configure IIS, you really should use app.UseFileServer () and locate the document in the database. This way you can simply remove and re-insert the application later.

+4
source

I know his question since 1.8 years, but if someone needs to solve the same problem, try using this:

 public void Configure(IApplicationBuilder app) { app.UseStaticFiles(); // For the wwwroot folder app.UseStaticFiles(new StaticFileOptions() { FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "images")), RequestPath = new PathString("/MyImages") }); } 

It is completely possible to change the PhysicalFileProvider settings to any local or shared folder, and the file serves with this.

Doing this this way is not recommended SAFETY. But, for research to suggest, its acceptable.

A static file module does not provide authorization. Any files served by him, including wwwroot, are publicly available. Listen to files based on authorization: Store them outside of wwwroot and any directory accessible for static middleware and serve them through the controller actions, returning FileResult where the authorization is attached.

In Microsoft Asp.Net docs, we can find more complete information to help with this problem.

Check out this link: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files

+1
source

My solution used path="/" instead of path="*" in the web.config file

0
source

Having the same / similar issue using ASP.NET CORE 2.1.

While the web files were stored in the / wwwroot / folder, I created a VIRTUAL DIRECTORY for this folder in IIS and looked through the folders and files correctly when browsing. However, the browser (http) does not pull them.

I solved my problem by creating a virtual directory outside the root.

WORKS THIS WAY:

WEB SITE

/ Wwwroot /

/ Css /

/ Js /

/ Library /

/ VIRTUAL FOLDER /

DOES NOT WORK THIS WAY:

WEB SITE

/ Wwwroot /

/ Css /

/ Js /

/ Library /

/ VIRTUAL FOLDER /

0
source

All Articles