Control how media types are resolved in EPiServer

Mari Jørgensen 28.09.2014 17:00:00

The new asset and media system was introduced in version 7.5 of EPiServer - working with media files is now following the exact same pattern as when working with other types of content such as pages and blocks. Media types can be for instance images, videos and documents and they need to be defined as content models before any media instances can be created.

Content media types

During initialization EPiServer CMS will scan all assemblies in the bin folder for .NET classes that inherits from MediaData and are decorated with [ContentType]-attribute (see example below). ImageData and VideoData are two specialized classes that allow the system to distinguish images and videos from other generic media in order to apply special handling in the user interface. Both ImageData and VideoData inherit from MediaData.

An example of how content type might be declared:

[ContentType(GUID = "625AFFB8-E206-4886-ABD0-213EF1345982")] 
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
public class SiteImageFile : ImageData
{
public virtual string Description { get; set; }
[ImageDescriptor(200,200)] public virtual Blob CustomThumbnail{ get; set;
}

When a file is uploaded EPiServer will use a ContentMediaResolver to find the correct type. If there are more than one type that matches the file extension (for instance ".jpg" files), EPiServer will simply pick the first they find.

Implementing a ContentMediaResolver

In my case, I had a several types for image defined - one was meant for product images originating from InRiver (using a specific interface), and the other one the standard type (SiteImageFile) when uploading images used as content on the site. To make sure that images uploaded by the editors through the asset pane were created as SiteImageFile content, I added my own ContentMediaResolver that inherited from the built-in one.

public class MyContentMediaResolver : ContentMediaResolver 
{ 
public override Type GetFirstMatching(string extension)
{
var selectedAsDefault = base.GetFirstMatching(extension); // For all image data, I want to use class SiteImageFile if(typeof(ImageData).IsAssignableFrom(selectedAsDefault))
return typeof(SiteImageFile); return selectedAsDefault;
}
}

Remember to register your class as an implementation for ContentMediaResolver so it will be used by EPiServer - this can be done either using ServiceConfigurationAttribute or through a IConfigurableModule implementation. Here is an example of the latter:

//inside your ConfigureContainer method of your IConfigurableModule 
container.For<ContentMediaResolver>().Use<MyContentMediaResolver>();

A final note: A cleaner solution for this issue would be to control this from the content type, for instance using a property "IsDefault" (or similar) of the MediaDescriptor attribute - I have added this as a feature request to EPiServer.