Hi – in our dev environment we have the Umbraco media in a shared/common location e.g. \\myserver\site-media
Im trying to follow https://our.umbraco.com/Documentation/Extending/FileSystemProviders/index-v9 to configure the Visual Studio dev environment with a “Media Filesystem” using this UNC location, but what about test and live environments that will be different? Is the a completely config-based way to achieve this rather than in code? In umbraco 7/8 we simply used a virtual directory defined in applicationhost.config but that doesn’t seem to work in the .net core world
Then because the configuration is now via code - could you read the appsetting value and only change the mediafilesystem in the composer when the environment is Not test or production?
eg wrap the code that changes the underlying mediafilesystem inside an If that checks the appsetting?
Did you manage to solve this issue? Did you go down the custom file system route with some kind of if-statement to only use the custom file system on Development? Or did you find another way to get this done?
If you wanted to configure the FileSystemProvider based on different environments, you could inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment into the constructor of the UserComposer example from the documenation.
Then with a reference to using Microsoft.Extensions.Hosting
you are able to then check the following
yes we had since worked out a solution along those lines but i forgot to say in this thread - good info for someone else finding this thread so thank you
I managed to get the custom location to work. However, this setup interferes with ImageSharp. Apparently ImageSharp only works when the image files are located in wwwroot. This new issue apparently can be fixed by implementing a custom IImageProvider. I was wondering if you ran into a similar issue with ImageSharp since you were serving your media files from a network share (clearly outside of wwwroot). If you did, how were you able to get ImageSharp to work?
hi Arjan, yes we also have this issue you describe with ImageSharp and a custom media virtual directory not playing nicely together. We had parked looking into this so haven't found a solution as yet. I would imagine this scenario is quite commonplace and it would be good for the core docs to provide some guidance on this.
using System.ComponentModel;
using Umbraco.Cms.Core.Configuration.Models;
namespace Application.Core.Models.Configuration
{
[UmbracoOptions("Application")]
public class ApplicationSettings
{
public MediaSettings Media { get; set; }
}
public class MediaSettings
{
public string RootPath { get; set; }
}
}
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
{ ... }
if (env.IsProduction() == false)
{
var mediaSettings = new MediaSettings();
_config.GetSection("Application").GetSection("Media").Bind(mediaSettings);
if (string.IsNullOrEmpty(mediaSettings.RootPath) == false)
{
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(mediaSettings.RootPath),
RequestPath = "/media"
});
}
}
}
MediaFileSystem.cs
using Application.Core.Extensions;
using Application.Core.Models.Configuration;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Infrastructure.DependencyInjection;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
namespace Application.Core.Composing
{
public class MediaFileSystemComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.SetMediaFileSystem((factory) =>
{
var webHostEnvironment = factory.GetRequiredService<IWebHostEnvironment>();
var hostingEnvironment = factory.GetRequiredService<IHostingEnvironment>();
var rootPath = hostingEnvironment.MapPathWebRoot("~/media");
var rootUrl = "/media";
if (webHostEnvironment.IsProduction() == false)
{
var mediaSettings = new MediaSettings();
builder.Config.GetSection("Application").GetSection("Media").Bind(mediaSettings);
if (string.IsNullOrEmpty(mediaSettings.RootPath) == false)
{
rootPath = mediaSettings.RootPath;
}
}
return new PhysicalFileSystem(
factory.GetRequiredService<IIOHelper>(),
hostingEnvironment,
factory.GetRequiredService<ILogger<PhysicalFileSystem>>(),
rootPath,
rootUrl);
});
}
}
}
This way I can use a shared folder on Development and Staging and the wwwroot/media folder on Production.
The previous code examples didn't play well with ImageSharp. But if anyone is looking for a working solution until Umbraco comes up with an out-of-the-box solution for this problem, please check out the following example:
Umbraco 9 and media folder location
Hi – in our dev environment we have the Umbraco media in a shared/common location e.g.
\\myserver\site-media
Im trying to follow https://our.umbraco.com/Documentation/Extending/FileSystemProviders/index-v9 to configure the Visual Studio dev environment with a “Media Filesystem” using this UNC location, but what about test and live environments that will be different? Is the a completely config-based way to achieve this rather than in code? In umbraco 7/8 we simply used a virtual directory defined in applicationhost.config but that doesn’t seem to work in the .net core world
Any pro tips? Thanks in advance!
Hi Andrew
Not really had a look at V9 yet but, could you have an appsetting flag for 'UseSharedMediaFileSystemOrSomething' in appsettings
which could then be different for each environment, using an appropriate
appsettings.{environment}.json file:
https://our.umbraco.com/documentation/Reference/V9-Config/
Then because the configuration is now via code - could you read the appsetting value and only change the mediafilesystem in the composer when the environment is Not test or production?
eg wrap the code that changes the underlying mediafilesystem inside an If that checks the appsetting?
regards
Marc
Did you manage to solve this issue? Did you go down the custom file system route with some kind of if-statement to only use the custom file system on Development? Or did you find another way to get this done?
Hi Andrew 👋
If you wanted to configure the FileSystemProvider based on different environments, you could inject
Microsoft.AspNetCore.Hosting.IWebHostEnvironment
into the constructor of the UserComposer example from the documenation.Then with a reference to
using Microsoft.Extensions.Hosting
you are able to then check the followinghttps://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-5.0
I hope this helps you to achieve what you want to.
Warren 😀
thanks Warren
yes we had since worked out a solution along those lines but i forgot to say in this thread - good info for someone else finding this thread so thank you
Andrew
Would you mind sharing your solution?
Hi Andrew,
I managed to get the custom location to work. However, this setup interferes with ImageSharp. Apparently ImageSharp only works when the image files are located in wwwroot. This new issue apparently can be fixed by implementing a custom IImageProvider. I was wondering if you ran into a similar issue with ImageSharp since you were serving your media files from a network share (clearly outside of wwwroot). If you did, how were you able to get ImageSharp to work?
Regards,
Arjan
hi Arjan, yes we also have this issue you describe with ImageSharp and a custom media virtual directory not playing nicely together. We had parked looking into this so haven't found a solution as yet. I would imagine this scenario is quite commonplace and it would be good for the core docs to provide some guidance on this.
thanks
Andrew
Yeah, it looks like the only way to get everything to play nicely together is by implementing a custom FileSystemProvider similar to AzureBlob:
https://our.umbraco.com/documentation/Extending/FileSystemProviders/Azure-Blob-Storage/
https://github.com/umbraco/Umbraco.StorageProviders
This is quite cumbersome for something that could be done with a simple virtual directory in IIS for Umbraco 8.
Yes those were my sentiments too, but i think thats more a aspnetcore thing than umbraco 9 as such
For those of you who are interested, I'm using the following setup:
appsettings.json (this can be omitted, because I'm only using the custom path settings on Development and Staging, but I left it in for clarity)
appsettings.Development.json
ApplicationSettings.cs
Startup.cs
MediaFileSystem.cs
This way I can use a shared folder on Development and Staging and the wwwroot/media folder on Production.
The previous code examples didn't play well with ImageSharp. But if anyone is looking for a working solution until Umbraco comes up with an out-of-the-box solution for this problem, please check out the following example:
https://github.com/umbraco/Umbraco-CMS/issues/11580#issuecomment-991716300
is working on a reply...