In this blog post, we explain how we extended Episerver to meet some functional requirements and improve the CMS editors' experience of working with images.
So what did we do?
- Added metadata fields for media and images
- Description – used as image alt text
- File Extension – used to show icons for media files
- File Size – used to display the size in Kb, Mb etc of media files
- Width and Height – used to build responsive image galleries
- Added support for vector based images
- Displaying SVG thumbnails
Extending the ImageData base class
In Episerver, ImageData is a base class that inherits from EPiServer.Core.MediaData and provides a Content Type to handle any type of image.
When a CMS editor uploads an image in Episerver DXC, the image is stored in Azure Blob storage and Episerver generates a thumbnail to help the CMS editor select images from the Media tab.
Adding Metadata fields
We needed to add metadata to images. To do this we created a new class that inherits from ImageData called ImageFile.
[ContentType(GUID = "0A89E464-56D4-449F-AEA8-2BF774AB8730")]
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
public class ImageFile : ImageData, IContentMediaMetaData
{
/// <summary>
/// Description of the Image
/// </summary>
public virtual string Description { get; set; }
/// <summary>
/// File extension of the Image file
/// </summary>
[Editable(false)]
public virtual string FileExtension { get; set; }
/// <summary>
/// File size of the Image file
/// </summary>
[Editable(false)]
public virtual int FileSize { get; set; }
/// <summary>
/// Width of the Image
/// </summary>
[Editable(false)]
public virtual int Width { get; set; }
/// <summary>
/// Height of the Image
/// </summary>
[Editable(false)]
public virtual int Height { get; set; }
}
You might have noticed we also implemented an interface called IContentMediaMetaData. We wanted to add some metadata fields to all our media, not just images, but you could choose to omit this interface.
public interface IContentMediaMetaData : IContentMedia
{
string FileExtension { get; set; }
int FileSize { get; set; }
}
Once this was done, we just had to upload an image in the CMS and our metadata fields were available.

Generating metadata
We're always trying to reduce unnecessary CMS editor data entry. The only field we really need a human to manually populate is the Description field.
So we added some helper methods to automatically populate the File Size, File Extension, Width and Height fields and added an InitializationModule with CreatingContent and SavingContent event handlers to set these field values.
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ContentMediaInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
var eventRegistry =
ServiceLocator.Current.GetInstance<IContentEvents>();
eventRegistry.CreatingContent += OnCreatingContent;
eventRegistry.SavingContent += OnSavingContent;
}
public void Preload(string[] parameters)
{
}
private void OnSavingContent(object sender, ContentEventArgs e)
{
if (e.Content is IContentMediaMetaData)
{
MediaHelpers.SetFileMetaData(e.Content as IContentMediaMetaData);
}
}
private static void OnCreatingContent(object sender, ContentEventArgs e)
{
if (e.Content is IContentMediaMetaData)
{
MediaHelpers.SetFileMetaData(e.Content as IContentMediaMetaData);
}
}
public void Uninitialize(InitializationEngine context)
{
var eventRegistry =
ServiceLocator.Current.GetInstance<IContentEvents>();
eventRegistry.CreatingContent -= OnCreatingContent;
eventRegistry.SavingContent -= OnSavingContent;
}
}
Now when we upload or even edit an image with the built-in Image Editor, our helper methods will automatically populate the metadata fields. With this automated, we decided to make these fields read only by adding the Attribute [Editable(false)] to the Properties in our ImageFile class.

Adding support for Vector based images
If you noticed the MediaDescriptor ExtensionString list on our ImageFile class, you maybe thinking you could just add svg to the list like this... We tried this too!
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png,svg")]
While this did allow SVGs to be handled by the ImageFile class, it did present some issues with both thumbnail generation and metadata generation.
- Thumbnail generation
Regardless of whether it's a Vector or Raster based image, Episerver will attempt to generate a thumbnail when you upload it. However, in the case of SVGs (vectors), the concept of a thumbnail is not relevant because they are already a scalable object. Episerver generates an empty thumbnail, but we really want it to use the original SVG.
The following image shows JPG thumbnails compared to SVG thumbnails.

- Metadata generation
Similarly, as they are infinitely scalable, Width and Height are not relevant for an SVG.
To solve these issues, we added another new Class called VectorImageFile to specifically support vector images, but don't worry, it inherits from the ImageFile class we created previously.
[ContentType(DisplayName = "VectorImageFile", GUID = "c0b70fd0-0d5b-4c53-83fe-e32ea8faa2d5", Description = "")]
[MediaDescriptor(ExtensionString = "svg")]
public class VectorImageFile : ImageFile, IContentMediaMetaData
{
/// <summary>
/// Gets the generated thumbnail for this media.
/// </summary>
public override Blob Thumbnail
{
get { return BinaryData; }
}
}
Take note of the Public Override Blob Thumbnail. As the name suggests, this overrides the base class and returns the BinaryData of the actual SVG rather than a generated thumbnail.
The only thing left to do is to prevent our helper from attempting to set the image Width and Height. This was as simple as adding a condition to our helper to check if the object type is VectorImageFile
if (media is VectorImageFile) return;
So how does all this look in the CMS?
Inside Episerver when we upload images in the Media tab of the Assets pane we now see the following...
JPGs in the Media tab
- The Description metadata field is available for editing
- The remaining Metadata fields have be automatically populated

SVGs in the Media tab
- The Thumbnails are displayed based on the binary data of the actual SVG
- The Description metadata field is available for editing
- The Width and Height fields have not been automatically populated
- The remaining Metadata fields have be automatically populated

Hiding or removing Width and Height fields from VectorImages
Now that the Width and Height fields are not longer being automatically populated, we wanted to hide them, so we were able to simply override them in the Class definition and add a [ScaffoldColumn(false)] or [Ignore] attribute to the Properties.
[ScaffoldColumn(false)]
public override int Width { get; set; }
[ScaffoldColumn(false)]
public override int Height { get; set; }

Wrapping it up
In this blog post we have covered how we have improved the CMS editors' experience when working with raster and vector images in Episerver, and how we extended the ImageData base class include and generate data for Metadata fields. We also added a VectorImage class to allow the CMS to display SVG thumbnails.
Need an agency with Episerver expertise?
Contact UsKeep Reading
Want more? Here are some other blog posts you might be interested in.