0

Can I map an arbitrary directory as a subdirectory of wwwroot? That is, the directory is not under wwwroot in the file system, but within my app, it is treated like so.

For example, I have created an ASP.NET 6.0 Blzor Server project. The programme dll path is in /app/proj1/BlazorApp1.dll. If there is an image at /app/proj1/wwwroot/images/dog.jpg, it can be rendered using <img src="images/dog.jpg"/> in my page. But what if I do not want to have this images directory actually under the wwwroot directory on the file system? Can the directory be somewhere else like /data/images, and I map that path to wwwroot/images, so that /data/images/dog.jpg can be rendered with <img src="images/dog.jpg"/> within my app?

Damn Vegetables
  • 11,484
  • 13
  • 80
  • 135
  • This is an ASP.NET Core /IIS question, not something managed by Blazor. In IIS you *can* have different sites and web apps appear below the default web site. In ASP.NET Core in general you can map different folders through `UseStaticFiles` – Panagiotis Kanavos Oct 31 '22 at 09:17

2 Answers2

0

You could try as below to update the default provider with a composite fileprovider :

var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
  Path.Combine(builder.Environment.ContentRootPath, "data"));

var compositeProvider = new CompositeFileProvider(webRootProvider,
                                                  newPathProvider);


app.Environment.WebRootFileProvider = compositeProvider;

app.UseStaticFiles();

Result:

enter image description here

Ruikai Feng
  • 6,823
  • 1
  • 2
  • 11
0

There are 3 ways to do this that i know of, Firstly adjusting the settings, which is clearly documented on msdn, under the 'Serve files outside of web root' header;

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
           Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
    RequestPath = "/StaticFiles"
});

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-6.0#serve-files-outside-of-web-root

For your case, since you want both wwwroot and another file, see 'Serve files from multiple locations';

var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
  Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles"));

var compositeProvider = new CompositeFileProvider(webRootProvider,
                                                  newPathProvider);

// Update the default provider.
app.Environment.WebRootFileProvider = compositeProvider;

app.UseStaticFiles();

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-6.0#serve-files-from-multiple-locations

Another way would be to use MSBuild to copy the files from another directory into the wwwroot folder, see for example the following SO;

Copy files to output directory using csproj dotnetcore

Lastly, and this is not as portable, you could use symlinks, see:

A symbolic link is a file-system object that points to another file system object. The object being pointed to is called the target.

Symbolic links are transparent to users; the links appear as normal files or directories, and can be acted upon by the user or application in exactly the same manner.

https://learn.microsoft.com/en-us/windows/win32/fileio/symbolic-links

https://en.wikipedia.org/wiki/Symbolic_link

https://superuser.com/questions/1020821/how-can-i-create-a-symbolic-link-on-windows-10

The first one should satisfy your needs.

sommmen
  • 6,570
  • 2
  • 30
  • 51
  • Does `PhysicalFileProvider` work on Windows? What if I want an arbitrary path, not a subdirectory of the content root path, like "C:\my\random\directory"? I tried it but it says path must be absolute and start with "/". That is a Linux path, not Windows. – Damn Vegetables Oct 31 '22 at 09:40
  • Yes, that should all work, i'm using it right now. You're on windows right? perhaps post the code you're using now in the question so we can have a better look. – sommmen Oct 31 '22 at 09:44
  • 1
    It seems that I misunderstood Visual Studio's error message. The IDE highlighted the entire block from `app` to `});` and the message was `System.ArgumentException: 'The path in 'value' must start with '/'. Arg_ParamName_Name'`, so I thought it was the path of the constructor argument of `PhysicalFileProvider`, but it turned out to be the value of the `RequestPath` parameter. I had used "pic" instead of "/pic". – Damn Vegetables Oct 31 '22 at 09:59