Sitecore Custom Media Request Handler to perform image name translation

Background: We have a client that uses inRiver as Product Information Management system. inRiver has a adapter for Sitecore that connects Sitecore to inRiver. The adapter works by creating and updating Sitecore items for Products, Categories, Images, etc. from the PIM. All Sitecore items created by the adapter have a name which has Ids from inRriver. For example a category image would have a name of 139442-720 and display name of 23475_CAT_0.jpg.

Problem: When referring to these images from the website we were in a way forced to use the name instead of the display name because Sitecore media request handler cannot lookup images by display name. We needed to be able to refer to the images using /-/media/inriver/23475_CAT_0.jpg instead of /-/media/inriver/139442-720

Solution: What we needed in essence is a custom Media Request Handler that would translate from the Display Name to the Item Name, retrieve the media stream and send the response to the browser. We decided to use the Solr index to do the lookup instead of using the Sitecore API for speed. We have an index that indexes the inriver media sitecore items. Now we can query this index using the DisplayName and get the Id based Item name back. Once we have the item name we can get the media using Sitecore MediaManager. After that its just a matter of copying the stream to the Response stream.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public class CustomMediaRequestHandler : MediaRequestHandler
    {
        public override void ProcessRequest(HttpContext context)
        {
            if (context.Request.Path.ToLower().Contains("/media/inriver/"))
            {
                var requestedFilename = Path.GetFileName(context.Request.Url.LocalPath);

                //we want to fallback to regular sitecore media handler if we don't need to do the translation
                if (!Regex.Match(requestedFilename, @"^\d{3,8}-\d{3,8}\.([a-z]|[A-Z]){2,4}$", RegexOptions.Compiled | RegexOptions.IgnoreCase).Success)
                {
                    var mediaItem = SearchHelper.GetMediaItemByResourceDisplayName(Path.GetFileNameWithoutExtension(requestedFilename), requestedFilename);

                    if (mediaItem == null)
                    {
                        Log.Warn("Can't find media item for url: " + context.Request.Url.LocalPath, this);
                    }

                    if (mediaItem != null)
                    {
                        Media media = MediaManager.GetMedia(mediaItem);
                        var fileExtention = Path.GetExtension(requestedFilename).ToLower();

                        context.Response.ContentType = ReturnMimeType(fileExtention);

                        if (fileExtention == ".png" || fileExtention == ".jpg" || fileExtention == ".jpeg")
                        {
                            var mediaOptions = GetMediaOptions(context);

                            using (var mediaStream = media.GetStream(mediaOptions))
                            {
                                mediaStream.CopyTo(context.Response.OutputStream);
                            }
                        }
                        else
                        {
                            using (var mediaStream = media.GetStream())
                            {
                                mediaStream.CopyTo(context.Response.OutputStream);
                            }
                        }
                        context.Response.Cache.SetCacheability(Settings.MediaResponse.Cacheability);
                        context.Response.Cache.SetMaxAge(Settings.MediaResponse.MaxAge);
                        context.Response.Flush();
                        context.Response.End();
                    }
                }
            }
            base.ProcessRequest(context);
        }

        private static MediaOptions GetMediaOptions(HttpContext context)
        {
            var mh = context.Request.QueryString.Get("mh");
            if(string.IsNullOrWhiteSpace(mh))
            {
                mh = context.Request.QueryString.Get("h");
            }

            var mw = context.Request.QueryString.Get("mw");
            if (string.IsNullOrWhiteSpace(mw))
            {
                mw = context.Request.QueryString.Get("w");
            }

            MediaOptions mo = new MediaOptions { BackgroundColor = Color.Transparent };

            if (!string.IsNullOrWhiteSpace(mh))
            {
                mo.MaxHeight = int.Parse(mh);
            }

            if (!string.IsNullOrWhiteSpace(mw))
            {
                mo.MaxWidth = int.Parse(mw);
            }
            return mo;
        }

        private string ReturnMimeType(string fileExtension)
        {
            fileExtension = fileExtension ?? string.Empty;
            switch (fileExtension.ToLower())
            {
                case ".gif":
                    return "image/gif";
                case ".png":
                    return "image/png";
                case ".tiff":
                case ".tif":
                    return "image/tiff";
                case ".jpg":
                case ".jpeg":
                    return "image/jpeg";
                case ".pdf":
                    return "application/pdf";
                case ".ai":
                case ".eps":
                    return "application/postscript";
                case ".zip":
                    return "application/zip";
                default:
                    return string.Empty;
            }
        }

    }