Quick Tip: Serving media from a live environment

So with all our projects at TRES, we don't want to store all the media in source control. But if we are working locally we want to have media visible. This means many developers download media from the Test environment and then run the site. This is quickly done for a simple site, but sometimes our sites contain Gigabytes of data. 

So why not manipulate the media URL to point to our test environment? So we don't have the media locally but from an environment containing bare essentials including images. 

This can be done using a MediaUrlProvider in Umbraco 10 and newer. 

Here I will give some basic code to do so.

First, we need a custom MediaUrlProvider, we call it DevelopmentMediaUrlProvider and this extends the DefaultMediaUrlProvider. 
We are gonna extend the DefaultMediaUrlProvider of Umbraco because it's working as expected only we want to point to a different domain url. 

 

public class DevelopmentMediaUrlProvider : DefaultMediaUrlProvider
{
    private readonly IWebHostEnvironment _environment;
    private readonly string _url;

    public DevelopmentMediaUrlProvider(MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility, IConfiguration configuration, IWebHostEnvironment environment) : base(mediaPathGenerators, uriUtility)
    {
        _environment = environment;
        _url = configuration.GetValue<string>("mediaUrlProvider:baseUrl");
    }

    public override UrlInfo? GetMediaUrl(IPublishedContent content, string propertyAlias, UrlMode mode, string? culture, Uri current)
    {
        if (_environment.IsDevelopment() && !string.IsNullOrWhiteSpace(_url))
        {
            var mediaUrl = base.GetMediaUrl(content, propertyAlias, mode, culture, current);
            if (mode == UrlMode.Absolute)
            {
                mediaUrl = base.GetMediaUrl(content, propertyAlias, mode:UrlMode.Relative, culture, current);
            }

            return UrlInfo.Url(_url + mediaUrl, culture);
        }

        return base.GetMediaUrl(content, propertyAlias, mode, culture, current);
    }
}

We first want to read the new URL from the app settings. This is done on line 9.

Then we override the  GetMediaUrl because we only want our logic to be used if the environment is in Development mode and if the setting is filled in. You can see this on line 14. So if you deploy this to production this logic is not gonna work and it falls back to the Umbraco version of Url Provider.

 

Then on line 17 we only check to see if the mode is set to Absolute. If so we change the call to Relative so no URL is provided. Next, we are gonna create a new UrlInfo with the combination of the setting and mediaUrl this way you have a URL that points to the external site and not your local site. 

So now we have a development media URL provider, but it's not working yet. This needs to be done by registering this version. 

This is done in a composer and here we are gonna clear the default media URL providers and add our own DevelopmentMediaUrlProvider

 

public class DevelopmentComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.MediaUrlProviders().Clear();
        builder.AddMediaUrlProvider<DevelopmentMediaUrlProvider>();
    }
}

And now if you are running your site in development mode you can see images from the online environment.

note: if the images aren't available on the environment you set in your app settings it still won't show an image.