This topic explains the concept of media types in Episerver, and describes how to define specialized media types when setting up an Episerver website. Like other content types, media types must first be defined in the content model, to be able to use built-in functionality such as uploading of files to the Media folder in edit view.
Note: When setting up your website, it is recommended that you create specific classes for media of type images, video, and anything generic other than video or image, such as text or PDF files.
How it works
Media and media types work as follows:
A media type defines a set of properties.
A media is an instance of the .NET class that defined the media type.
When an editor creates/uploads media, values are assigned to the properties defined by the media type.
When an instance of media is requested by a visitor, the default media handler sends the binary data to the visitor.
The content model specifies available media types, no built-in media types exist.
During initialization, assemblies in the bin folder are scanned for .NET classes decorated with [ContentType] attribute, and inheriting from MediaData. Meta data for media is defined as properties on the media class, and can be edited from edit view.
Generic media type
The example below shows a generic media type for handling files, inheriting from MediaData, with a description property available under the Content tab in edit view.
using System;
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.Framework.DataAnnotations;
namespace MyEpiserverSite.Models.Media
{
[ContentType(DisplayName = "GenericMedia", GUID = "89761dbb-bf22-4cee-93c7-9d661d75cad8", Description = "Used for generic file types such as Word or PDF documents.")]
[MediaDescriptor(ExtensionString = "pdf,doc,docx")]
public class GenericMedia : MediaData
{
[CultureSpecific]
[Editable(true)]
[Display(
Name = "Description",
Description = "Add a description of the content.",
GroupName = SystemTabNames.Content,
Order = 1)]
public virtual String Description { get; set; }
}
}
MediaDescriptor attribute
The MediaDescriptor attribute defines a list of file extensions and associates specific file types with a given content type, which creates content of the correct content type when a user uploads media via the user interface.
When you create media content from the server side, you also can have this same content type resolve by using the ContentMediaResolver.
Specialized media types
ImageData and VideoData are specialized base classes distinguishing images and videos from other generic media, to apply special handling in edit view. For example, media types inheriting ImageData will display image thumbnails when listing images in the Media folder in edit view. Both ImageData and VideoData inherit from MediaData.
Example: Media type for images, inheriting from ImageData, and with properties for copyright and a description.
namespace MyEpiserverSite.Models.Media
{
[ContentType(DisplayName = "ImageFile", GUID = "875b3b51-e0a7-412c-8f56-44f59c184440", Description = "Used for images of different file formats.")]
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
public class ImageFile : ImageData
{
//// <summary>
/// Gets or sets the copyright.
/// </summary>
public virtual string Copyright { get; set; }
public virtual String Description { get; set; }
}
}
Example: Media type for videos, inheriting from VideoData, and with properties for copyright and link to video preview image.
namespace MyEpiserverSite.Models.Media
{
[ContentType(DisplayName = "VideoFile", GUID = "f2285e5a-be15-47b6-8952-e3c61deaefd2", Description = "Used for specific video file formats.")]
[MediaDescriptor(ExtensionString = "flv,mp4,webm")]
public class VideoFile : VideoData
{
/// <summary>
/// Gets or sets the copyright.
/// </summary>
public virtual string Copyright { get; set; }
/// <summary>
/// Gets or sets the URL to the preview image.
/// </summary>
[UIHint(UIHint.Image)]
public virtual ContentReference PreviewImage { get; set; }
}
}
ImageDescriptor attribute
The ImageDescriptor attribute automatically generates scaled images. When you route to a BLOB type property, Episerver determines whether the BLOB is null and the property has an ImageDescriptor attribute. If both are true, a scaled image is automatically generated from IBinaryStorable.BinaryData.
Example: The ImageData.Thumbnail property with an ImageDescriptor attribute.
/// <summary>
/// Base class for content types which should be handled as images by the system.
/// </summary>
public class ImageData : MediaData
{
/// <summary>
/// Gets or sets the generated thumbnail for this media.
/// </summary>
[ImageDescriptor(Width = 48, Height = 48)]
public override Blob Thumbnail
{
get { return base.Thumbnail; }
set { base.Thumbnail = value; }
}
}
Customizing the media handler
The built-in EPiServer.Web.ContentMediaHttpHandler delivers all media by default. However, if you want custom processing before sending the media to the visitor, the example below shows how you can implement your own HTTP handler. Handlers for media uses the same templating system as other content types in Episerver, which means you can use any type of template for media; you are not limited to HTTP handlers.
public partial class CustomFileHandler : IHttpHandler, IRenderTemplate<CustomFile>
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
//Get file content
var routeHelper = ServiceLocator.Current.GetInstance<ContentRouteHelper>();
var content = routeHelper.Content;
if (content == null)
{
throw new HttpException(404, "Not Found.");
}
//Check access
if (!content.QueryDistinctAccess(AccessLevel.Read))
{
var accessDenied = DefaultAccessDeniedHandler.CreateAccessDeniedDelegate();
accessDenied(this);
return;
}
//Cast to custom file
var customFile = content as CustomFile;
if (customFile == null || customFile.BinaryData==null)
{
throw new HttpException(404, "Not Found.");
}
//Set caching policy
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));
//Do custom processing
//TransmitProcessedFile(customFile.BinaryData)
}
}
Media structure
Media is structured using folders. A folder in the media structure can have other folders or media as children, but a media instance cannot have any children. You can set access rights on folders to control availability for editors.
The media structure is defined by the following criteria:
The global media root folder is set as GlobalAssetsRoot, defining media available for content on all sites in a mult-site scenario.
A site-specific media root folder is set as SiteAssetsRoot, defining media only available for a specific site in a multi-site scenario. In a single site scenario, the GlobalAssetsRoot and SiteAssetRoot will typically point to the same folder.
A folder is an instance of ContentFolder, and is used to structure content. A content folder does not have any associated rendering, and will not appear on the site.
Changing the maximum upload file size
In web.config, change the parameters maxAllowedContentLength and maxRequestLength: