Try our conversational search powered by Generative AI!

K Khan
Dec 10, 2014
  5304
(5 votes)

Using Blobs and CDN both effectively

We have a requirement where Editors can upload images on cloud and use those from website.

We implemented a blob provider to let editors upload and use their images on cloud (cloudinary.com) http://world.episerver.com/code/K-Khan-/Cloudinary-Implementation-in-Blob/

But there were few issues with this implementation, as on presenting the images on website in OpenRead function of provider, we have to download this images in Memory. To read image in memory. That means extra bandwidth usage and using server resources unnecessary. Another option was to redirect to CDN in provider. That means a 302 status and a Error in log files (http://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=113925). With redirection we have another issue that In Online centre Catalog module was not able to prepare thumbnails.

To deal with these issues we solved it by translating images from globalassets/image.jpg to direct CDN url http://res.cdn.com/account/1537157355371237123.jpg and for Editors we kept the original implementation. This can be useful in many other cases also.

Requirement:
Change <img src="/globalassets/logo.png" alt="" class="" itemprop="logo"> to url in cdn <img src=http://res.cloudinary.com/example.png alt="" class="" itemprop="">

Solution:
I got the help of Johan's solution in some forum post he advised. In initialization module overload ContentRoute.CreatedVirtualPath

ContentRoute.CreatedVirtualPath += this.ReplaceWithCloudUrl;
CatalogRouteHelper.MapDefaultHierarchialRouter(RouteTable.Routes, true);

public void ReplaceWithCloudUrl(object source, UrlBuilderEventArgs eventArgs)
        {
            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

            ////Check if routed content is a IBinaryStorable with a Cloudinary Blob, if so replace url with cdn blob uri      
            object contentReferenceObject;
            if (eventArgs.RouteValues.TryGetValue(RoutingConstants.NodeKey, out contentReferenceObject))
            {
                ContentReference routedContentLink = contentReferenceObject as ContentReference;
                if (!ContentReference.IsNullOrEmpty(routedContentLink))
                {
                    var binaryContent = contentLoader.Get<IContent>(routedContentLink) as IBinaryStorable;
                    if (binaryContent != null)
                    {
                        ////Check that Everyone has Read access before switching to external url
                        ISecurable securable = binaryContent as ISecurable;
                        if (securable != null)
                        {
                            if ((securable.GetSecurityDescriptor().GetAccessLevel(PrincipalInfo.AnonymousPrincipal) & AccessLevel.Read) != AccessLevel.Read)
                            {
                                return;
                            }
                        }

                        var cloudinaryBlob = binaryContent.BinaryData as CloudinaryFileBlob;
                        var httpContext = System.Web.HttpContext.Current.GetRequestContext().HttpContext;
                        if (cloudinaryBlob != null && (!httpContext.Request.Path.ToLower().Contains(SiteConstants.EditingUrlPart.AppSetting())))
                        {
                            imagePath = //CDN Image Path that Blob;
                           
                            UrlBuilder cdnUrlBuilder = new UrlBuilder(imagePath);
                            eventArgs.UrlBuilder.Uri = cdnUrlBuilder.Uri;
                        }
                    }
                }
            }
        }

Dec 10, 2014

Comments

K Khan
K Khan Dec 10, 2014 06:57 PM

Will be happy to hear, how other tech masters resolved this type of issues?

Dec 10, 2014 08:40 PM

This is awesome. This is how blobs should be served!

Frederik Vig
Frederik Vig Dec 10, 2014 09:39 PM

We´ve done similar, but instead we´ve used the IIS extension URL Rewrite to rewrite ouput URLs to the CDN version. The CDN adds the image cached, if it didn´t have the image it would contact EPiServer and get the right image, then put it in it´s cache and serve it to the end user. Like a reverse proxy basically.

Frederik

Please login to comment.
Latest blogs
Azure AI Language – Extractive Summarisation in Optimizely CMS

In this article, I demonstrate how extractive summarisation, provided by the Azure AI Language platform, can be leveraged to produce a set of summa...

Anil Patel | Apr 26, 2024 | Syndicated blog

Optimizely Unit Testing Using CmsContentScaffolding Package

Introduction Unit tests shouldn't be created just for business logic, but also for the content and rules defined for content creation (available...

MilosR | Apr 26, 2024

Solving the mystery of high memory usage

Sometimes, my work is easy, the problem could be resolved with one look (when I’m lucky enough to look at where it needs to be looked, just like th...

Quan Mai | Apr 22, 2024 | Syndicated blog

Search & Navigation reporting improvements

From version 16.1.0 there are some updates on the statistics pages: Add pagination to search phrase list Allows choosing a custom date range to get...

Phong | Apr 22, 2024