Ben Nitti
Opal Administrator CertificationCommerce Connect 14 Developer CertificationPaaS CMS Developer Certification +1
Apr 22, 2021
visibility 3050
star star star star star
(3 votes)

Retrieving, storing file size information during upload

While presenting media content available for public download, it might be helpful to provide the file size, particularly for mobile users who may not want to save large files to their phone. 

This can be performed on any IContentMedia type by extending the content model and using an initialization module to retrieve and save the file size information. 

For this example, I'll create a custom media type for storing PDF, Word and Excel documents with a read only property to store the file size:

    [MediaDescriptor(ExtensionString = "pdf,docx,xlsx")]
    public class DocumentMediaType : MediaData, IHasFileSize
    {
        [Editable(false)]
        [Display(Order = 10, GroupName = SystemTabNames.Settings, Name = "File Size")]
        public virtual string FileSize { get; set; }
    }

I'm implementing an interface I called IHasFileSize:

    public interface IHasFileSize
    {
        string FileSize { get; set; }
    }

After that I can create the initialization module and attach to the save and create events to store the file size data:

    [InitializableModule]
    [ModuleDependency(typeof(ServiceContainerInitialization))]
    public class FileBasedEventsInitialization : IInitializableModule
    {
        // attach to both the CreatingContent and SavingContent events
        public void Initialize(InitializationEngine context)
        {
            IContentEvents eventRegistry = ServiceLocator.Current.GetInstance<IContentEvents>();

            eventRegistry.CreatingContent += SavingMedia;
            eventRegistry.SavingContent += SavingMedia;
        }

        private void SavingMedia(object sender, EPiServer.ContentEventArgs e)
        {

            if (!(e.Content is IContentMedia))
                return;

            IContentMedia media = e.Content as IContentMedia;

            string fileSize = GetFileSizeDisplay(media);

            if (media is IHasFileSize file)
            {
                file.FileSize = fileSize;
            }
        }

        private string GetFileSizeDisplay(IContentMedia media)
        {
            if (media?.BinaryData != null)
            {
                using (var stream = media.BinaryData.OpenRead())
                {
                    return FormatBytes(stream.Length);
                }
            }

            return string.Empty;
        }

        public void Uninitialize(InitializationEngine context)
        {
            IContentEvents eventRegistry = ServiceLocator.Current.GetInstance<IContentEvents>();

            eventRegistry.CreatingContent -= SavingMedia;
            eventRegistry.SavingContent -= SavingMedia;
        }

    }

This method is used for formatting the file size with the correct unit of measurement:

        private static string FormatBytes(long bytes)
        {
            string[] uom = { "B", "KB", "MB", "GB" };

            int i;

            double size = bytes;

            for (i = 0; i < uom.Length && bytes >= 1024; i++, bytes /= 1024)
            {
                size = bytes / 1024.0;
            }

            return $"{size:0.##} {uom[i]}";
        }

Thanks for reading, and enjoy displaying your new custom FileSize property!



Apr 22, 2021

Comments

error Please login to comment.
Latest blogs
Surviving a Dirty Feed. Part 3: Error Handling and Event Batching

Committing a 250,000-row Optimizely catalog import row by row, returning a per-row failure report, and coalescing catalog events into one per batch.

Stanisław Szołkowski | Oct 16, 2026 |

Building UI Extensions for Optimizely SaaS CMS

Introduction Developers have been extending the functionality of Optimizely PaaS CMS for years using addons built in C# and deployed as NuGet...

Mark Stott | Oct 15, 2026

Cheapskate AI Translator: Because Translation Should Not Require a Second Mortgage

There is a particular kind of software project that begins with a detailed architecture document, a product roadmap, and a carefully assembled...

Linh Doan Cuu | Oct 15, 2026

Computed Fields in CMS 13 Content Contracts with Optimizely Graph

Content Contracts in Optimizely CMS 13 allow different content types to share a common structure when querying Optimizely Graph. But what if the...

Mardy | Oct 14, 2026