Stephan Lonntorp
Nov 18, 2016
  3413
(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
Optimizely Forms: You cannot submit this form because an administrator has turned off data storage.

Do not let this error message scare you, the solution is quite simple!

Tomas Hensrud Gulla | Oct 4, 2024 | Syndicated blog

Add your own tools to the Optimizely CMS 12 admin menu

The menus in Optimizely CMS can be extended using a MenuProvider, and using the path parameter you decide what menu you want to add additional menu...

Tomas Hensrud Gulla | Oct 3, 2024 | Syndicated blog

Integrating Optimizely DAM with Your Website

This article is the second in a series about integrating Optimizely DAM with websites. It discusses how to install the necessary package and code t...

Andrew Markham | Sep 28, 2024 | Syndicated blog

Opticon 2024 - highlights

I went to Opticon in Stockholm and here are my brief highlights based on the demos, presentations and roadmaps  Optimizely CMS SaaS will start to...

Daniel Ovaska | Sep 27, 2024

Required fields support in Optimizely Graph

It's been possible to have "required" properties (value must be entered) in the CMS for a long time. The required metadata haven't been reflected i...

Jonas Bergqvist | Sep 25, 2024

How to write a bespoke notification management system

Websites can be the perfect vehicle for notifying customers of important information quickly, whether it’s the latest offer, an operational message...

Nicole Drath | Sep 25, 2024