Stephan Lonntorp
Nov 18, 2016
  4005
(2 votes)

Ensuring image extension for content URLs

When using an image resizing component, like we do in the Focal Point plugin, it's really important that the file extension is there. If it's not, the resizing engine won't kick in for the request, and that enormous image is sent straight to your mobile users, and they will forever hate your guts.

I've implemented a solution using the new (in CMS 10) IUrlSegmentCreator events, and a regular InitializationModule. Code below. It uses the first registered extension for your media type as the default extension for the URL segment. This works for me, since I have separate Media types for all image files, like JpegImage, PngImage etc, to be able to more granularly control their usage, through the AllowedTypes attribute. If you have a single MediaData for all your images, I recommend altering the extension mapping to maybe use the MimeType property and get an appropriate extension based on that. 

/*using System;
using System.IO;
using System.Linq;

using EPiServer;
using EPiServer.Core;
using EPiServer.Framework;
using EPiServer.Framework.DataAnnotations;
using EPiServer.Framework.Initialization;
using EPiServer.Web;
*/

[InitializableModule, ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
	public class ImageDataInitialization : IInitializableModule {
		private bool eventsAttached;
		public void Initialize(InitializationEngine context) {
			if(!this.eventsAttached) {
				var creator = context.Locate.Advanced.GetInstance<IUrlSegmentCreator>();
				creator.Created += CreatedMediaSegment;
				this.eventsAttached = true;
			}
		}
		private static void CreatedMediaSegment(object sender, UrlSegmentEventArgs e) {
			var content = e.Content as ImageData;
			if(content != null) {
				var extension = Path.GetExtension(content.RouteSegment);
				if(string.IsNullOrWhiteSpace(extension)) {
					var type = content.GetOriginalType();
					var fileExtension = GetExtensionForType(type);
					if(!string.IsNullOrWhiteSpace(fileExtension)) {
						content.RouteSegment = content.RouteSegment + "." + fileExtension;
					}
				}
			}
		}
		private static string GetExtensionForType(Type contentType) {
			var mediaDescriptorAttribute = contentType?.GetCustomAttributes(typeof(MediaDescriptorAttribute), false).OfType<MediaDescriptorAttribute>().FirstOrDefault();
			return mediaDescriptorAttribute?.Extensions?.FirstOrDefault();
		}
		public void Uninitialize(InitializationEngine context) {
			var creator = context.Locate.Advanced.GetInstance<IUrlSegmentCreator>();
			creator.Created -= CreatedMediaSegment;
			this.eventsAttached = false;
		}
	}
Nov 18, 2016

Comments

valdis
valdis Nov 22, 2016 09:55 PM

I'm not fan of hacks, but theoretically if you happen to have project with extension less images (which is weird) in it, you can tell IR to kick-in. See Nathanael answer.

http://stackoverflow.com/questions/14387595/imageresizer-and-image-files-without-an-extension

Stephan Lonntorp
Stephan Lonntorp Nov 22, 2016 10:27 PM

Thanks, but that seems like a can of worms. I cannot know all paths that csn, or cannot, contain an image. I think I'll stick with this approach. :)

Please login to comment.
Latest blogs
Missing Properties tool for Optimizely CMS

If you have been working with Optimizely CMS for a while you have probably accumulated some technical debt in your property definitions. When you...

Per Nergård (MVP) | Mar 10, 2026

AI Generated Optimizely Developer Newsletter

Updates in the Optimizely ecosystem are everywhere: blog posts, forums, release notes, NuGet packages, and documentation changes. This newsletter...

Allan Thraen | Mar 10, 2026 |

Lessons from Building Production-Ready Opal Tools

AI tools are becoming a normal part of modern digital platforms. With  Optimizely Opal , teams can build tools that automate real tasks across the...

Praful Jangid | Mar 7, 2026

My Takeaway from Optimizely Opal Agents in Action 2026 - What Agentic AI Means for the Future of Digital Marketing

I would like to share with you what stayed in my head after this amazing virtual event organized by Optimizely. Agents in Action 2026 , a live...

Augusto Davalos | Mar 6, 2026