CMS UI and SVGs

Vote:
 

Hi All,

Really enjoying the UI enhancement to display thumbnail images when used in the CMS. However, when using SVGs the thumbnail doesn't render:

Any ideas on how to fix this?

Alex

#201752
Mar 01, 2019 10:18
Vote:
 

Actually, I just checked the server logs and saw quite a 500s

System.ArgumentNullException:
   at System.Web.Caching.CacheEntry..ctor (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at System.Web.Caching.CacheInternal.DoInsert (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at System.Web.Caching.AspNetCache.Add (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at System.Web.Caching.Cache.Add (System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
   at EPiServer.Cms.Shell.UI.Controllers.Internal.ThumbnailController.Generate (EPiServer.Cms.Shell.UI, Version=11.17.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7)
   at lambda_method (Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (System.Web.Mvc, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.ControllerActionInvoker+<>c__DisplayClass24_0.<InvokeActionMethodWithFilters>b__0 (System.Web.Mvc, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction (System.Web.Mvc, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)

So I'll be raising a ticket with Support to see if it's something they can help with.

#201753
Mar 01, 2019 10:26
Vote:
 
#201764
Edited, Mar 01, 2019 15:30
Vote:
 

Hi Mattias,

thanks - EPiServer Support linked me to the same resource. we do indeed have that in our codebase already and it works great in the media pane or image select dialog for example, but for properties which are rendered with UIHint.Image not so much. 

I was inspecting the html for each and can see a difference. for example in the media panel an svg is rendered with the following:

<img src="/EPiServer/CMS/Content/siteassets/images/illustrations/advanced_cloud_2017_80_cyber_attacks.svg,,21088/Thumbnail?epieditmode=False?1551451382233" class="epi-floatLeft epi-thumbnail">

but in the teaser image (screenshot above):

<img data-dojo-attach-point="thumbnail" src="/EPiServer/CMS/Thumbnail/Generate/?contentLink=12303&amp;epi.preventCache=1551448945766">

So I'm guessing it's to do with whatever code is behind that generate thumbnail, but I can't seem to find too much documentation on it. If I put a contentLink number in for a file which isn't an svg then it returns a thumbnail, but for one which is an svg I get a 500 error.

 

#201766
Mar 01, 2019 15:47
Vote:
 

Ok, then this should be filed as a bug.

#201767
Mar 01, 2019 16:01
Vote:
 

Bug File (but may not be publically viewable just yet) CMS-13486 - SVG thumbnail doesn't render in "All properties" 

#201815
Mar 04, 2019 11:14
Vote:
 

The status of this bug is set Closed, Won't Fix

#202666
Mar 28, 2019 17:37
Vote:
 

Ok, so how are we supposed to work with SVGs within the CMS? Maybe a way to extend the thumbnail functionality? I mean in this case we could just return the URL to the SVG instead of resized image.

#202672
Mar 28, 2019 18:05
Vote:
 

Is thier anyway I can go back to using the old Image UiHint ? 

This is causing 500 errors on site hosted on DXC which is causing site to restart 

2019-03-28 17:04:17,520 [212] ERROR EPiServer.Global: Unhandled exception in ASP.NET
System.ArgumentNullException: Value cannot be null.
Parameter name: value
   at System.Web.Caching.CacheEntry..ctor(String key, Object value, CacheDependency dependency, CacheItemRemovedCallback onRemovedHandler, DateTime utcAbsoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, Boolean isPublic, CacheInternal cache)
   at System.Web.Caching.CacheInternal.DoInsert(Boolean isPublic, String key, Object value, CacheDependency dependencies, DateTime utcAbsoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback, Boolean replace)
   at System.Web.Caching.AspNetCache.Add(String key, Object item, CacheInsertOptions options)
   at System.Web.Caching.Cache.Add(String key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
   at EPiServer.Cms.Shell.UI.Controllers.Internal.ThumbnailController.Generate(ContentReference contentLink)
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass24_0.<InvokeActionMethodWithFilters>b__0()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at EPiServer.Shell.Web.Mvc.ModuleMvcHandler.ProcessController(IController controller)
   at EPiServer.Shell.Web.Mvc.ModuleMvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.<>c__DisplayClass285_0.<ExecuteStepImpl>b__0()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
System.ArgumentNullException: Value cannot be null.
Parameter name: value
   at System.Web.Caching.CacheEntry..ctor(String key, Object value, CacheDependency dependency, CacheItemRemovedCallback onRemovedHandler, DateTime utcAbsoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, Boolean isPublic, CacheInternal cache)
   at System.Web.Caching.CacheInternal.DoInsert(Boolean isPublic, String key, Object value, CacheDependency dependencies, DateTime utcAbsoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback, Boolean replace)
   at System.Web.Caching.AspNetCache.Add(String key, Object item, CacheInsertOptions options)
   at System.Web.Caching.Cache.Add(String key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
   at EPiServer.Cms.Shell.UI.Controllers.Internal.ThumbnailController.Generate(ContentReference contentLink)
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass24_0.<InvokeActionMethodWithFilters>b__0()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at EPiServer.Shell.Web.Mvc.ModuleMvcHandler.ProcessController(IController controller)
   at EPiServer.Shell.Web.Mvc.ModuleMvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.<>c__DisplayClass285_0.<ExecuteStepImpl>b__0()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

#202674
Mar 28, 2019 18:07
Vote:
 

We'll that status is disappointing. I've asked for a reason as to why it's a won't fix considering it's causing the 500 errors (We're also seeing them Minesh!)

@Johan, this is a dojo piece of code that we'd have to extend, right? I'm not a fan of having to mess around with that as it could potentially make the upgrade path more troublesome.

#202698
Mar 29, 2019 9:16
Vote:
 

@Alex I have updated my property to use the MediaFile UIHint as this doesnt have a preview on page doesnt cause 500, its a work around and not great but as Episerver will not be fixing the issue only way I could resolve it 

        [Display(Name = "Icon", Description = "Icon", Order = 200)]
        [Required]
        [UIHint(UIHint.MediaFile)]
        [AllowedTypes(typeof(ImageFile))]
        public virtual ContentReference ServiceIcon { get; set; }
#202733
Mar 29, 2019 14:07
Vote:
 

@Minesh, that is not a bad approach at all! :) I've been cheeky and asked for a reason why it's a no fix. To support's credit they did provide some (untested) code which a partner had submitted to them.

[ContentType(GUID = "AFE2F33B-57E1-484E-8D8F-057E3303DAF1")]
[MediaDescriptor(ExtensionString = "svg")]
public class VectorImageFile : ImageData
{
    /// <summary>
    /// Gets the generated thumbnail for this awesome vector image.
    /// </summary>
    public override Blob Thumbnail => BinaryData;
}

/// <remarks>
/// Override to make SVGs pop up in properties with UIHint.Image. --
/// </remarks>
public class ThumbnailController : Controller
{
    private readonly IContentRepository _contentRepository;
    private readonly ILogger _log;
    private readonly IMimeTypeResolver _mimeTypeResolver;
    private readonly ThumbnailManager _thumbnailManager;

    public ThumbnailController(
        ILogger log,
        IContentRepository contentRepository,
        ThumbnailManager thumbnailManager,
        IMimeTypeResolver mimeTypeResolver)
    {
        _log = log;
        _contentRepository = contentRepository;
        _thumbnailManager = thumbnailManager;
        _mimeTypeResolver = mimeTypeResolver;
    }

    public ActionResult Generate(ContentReference contentLink)
    {
        var realController = new EPiServer.Cms.Shell.UI.Controllers.Internal.ThumbnailController(_contentRepository, _thumbnailManager, _mimeTypeResolver)
        {
            ControllerContext = ControllerContext
        };
        try
        {
            return realController.Generate(contentLink);
        }
        catch (ArgumentNullException)
        {
            if (_contentRepository.TryGet(contentLink, out VectorImageFile content))
            {
                _log.Debug($"Error generating thumb for {contentLink}. Use vector {content.Name} directly instead");
                Blob binaryData = content.BinaryData;

                return File(binaryData.ReadAllBytes(), content.MimeType, content.Name);
            }

            throw;
        }
    }
}

But I've not been able to get it working as I think it's utilising a component that isn't available in CMS v11+. I'm getting the following error:

iisexpress.exe Error: 0 : Exception calling ImageService RenderImage method (System.NotSupportedException: No imaging component suitable to complete this operation was found. ---> System.Runtime.InteropServices.COMException: The component cannot be found. (Exception from HRESULT: 0x88982F50)
   --- End of inner exception stack trace ---
   at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
   at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
   at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
   at System.Windows.Media.Imaging.BitmapImage.EndInit()
   at EPiServer.ImageLibrary.ImageLib.LoadBitmapSource(Stream sourceStream, BitmapCreateOptions options)
   at EPiServer.ImageLibrary.ImageService.RenderImage(Byte[] imageBuffer, IEnumerable`1 operations, String mimeType, Single zoomFactor, Int32 jpegQuality)
   at EPiServer.ImageLibrary.ImageServiceClient.RenderImage(Byte[] imageBuffer, IEnumerable`1 operations, String mimeType, Single zoomFactor, Int32 jpegQuality)).
Failed to load resource: the server responded with a status of 500 (Internal Server Error) [http://localhost:49945/EPiServer/CMS/Thumbnail/Generate/?contentLink=24242&epi.preventCache=1553865266105]

Might be something to do with my configuration (or lack thereof), hopefully I'll time next week to explore.

#202738
Mar 29, 2019 15:29
Vote:
 

Alex, we will fix that in the upcoming release. Both 500 & the broken image inside the editor.

#202942
Apr 04, 2019 10:02
Vote:
 

Legends Bartosz!

#203009
Apr 05, 2019 16:43