2

I am using the display name for my files to localize the filename, I've written a pipeline that shows the display name in the HTML (that works), but when I try to download the files like pdf's then, the name of the downloaded file is still the item name and not the display name.

So I think I need to overwrite some pipelines like "media:request" (expample) but this pipeline seems not to work because it's not triggering when I try to download pdf files only on images.

Someone knows what I need to patch or overwrite to set the right

 Content-Disposition

Header or something else that allows me to use the display name as download filename.

Here you can see the Link which is created enter image description here

Here you can see the download name

enter image description here

Here you can see the Item name "broschueren123" and the display name "MyBroschueresDisplayName" enter image description here

I've also asked the Support and they told me: "File Download name is always Item name, not the Displayname" - so I need some custom implementation.

4
  • Do you just render a link to a pdf file from media library ( like `/-/media/pdf-display-name.pdf' )? And then click that link and it's downloading the file with item name instead of display name?
    – Marek Musielak
    Commented Nov 5, 2019 at 15:34
  • @MarekMusielak yes, I've added a screenshot above Commented Nov 6, 2019 at 6:36
  • You want it for all the media items or specific media items only? Commented Nov 8, 2019 at 6:24
  • Why would you have language specific display names for a PDF? presumably the PDF content is in one language. There would be several PDFs no, one per language?
    – Mark Cassidy
    Commented Nov 8, 2019 at 10:32

1 Answer 1

6
+150

In order to change file's download name, you can add a handler to media:request event. It catches all media requests, including requests for pdf files. In the handler you can modify Content-Disposition header to contain item display name + file extension.

Similarly to how it is shown in the example you have linked, you can take advantage of HttpResponse.AddOnSendingHeaders method to change the header value. The method is used to register a callback that the ASP.NET runtime will invoke immediately before response headers are sent for this request.

The code below was tested and it works to change file's download name for pdf files, as well as other media files and images. It is important to set conditions in the handler to run it only when it is needed, depending on what are the requirements. For example, you would definitely want to prevent this handler from being executed for shell site, otherwise it might trigger downloading of media files when you open media items in Sitecore Content Editor. Additionally, you might want to run it only for certain file types (e.g. pdf) or only if there is a certain query string parameter is present. Please check this blog post from Anders Laub.

A display name and a file extension can be retrieved from the corresponding properties of MediaItem:

using Sitecore.Data.Items;
using Sitecore.Events;
using Sitecore.Resources.Media;
using System;
using System.Web;

namespace CustomMediaEventHandlers
{
    public class ChangeFileNameEventHandler
    {
        public void OnMediaRequest(object sender, EventArgs args)
        {
            // must apply strict conditions here in order not to invoke it unnecessarily;
            // e.g. exclude shell site, invoke only for pdf files or only if  a certain query string parameter is present
            if (Sitecore.Context.Site.Name.Equals(Sitecore.Constants.ShellSiteName, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            SitecoreEventArgs eventArgs = args as SitecoreEventArgs;

            if (!(eventArgs?.Parameters?[0] is MediaRequest mediaRequest))
            {
                return;
            }

            MediaItem mediaItem = MediaManager.GetMedia(mediaRequest.MediaUri).MediaData.MediaItem;
            if (mediaItem == null || !IsPdfRequest(mediaItem))
            {
                return;
            }

            HttpRequest request = mediaRequest.InnerRequest;

            request.RequestContext.HttpContext.Response.AddOnSendingHeaders(context =>
            {
                context.Response.Headers["Content-Disposition"] = string.Format(
                    "attachment; filename={0}.{1}", 
                    mediaItem.DisplayName, 
                    mediaItem.Extension);
            });
        }

        private static bool IsPdfRequest(MediaItem mediaItem)
        {
            return mediaItem.Extension.Equals("pdf", StringComparison.OrdinalIgnoreCase) 
                || mediaItem.MimeType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase);

        }
    }
}

Note: If you have tried a similar approach and the event handler was not invoked, it can happen when a browser cached the file and it does not make a request to the server. Please be aware that when using Chrome, clearing site data (cache storage and application cache) from Dev tools panel will not have an effect on disk cache. In the Network tab, Size column, it will still show 'from disk cache' and in the request headers it will say "Provisional headers are shown" because it did not do an actual request to the server. If this is the case, you can try using an Incognito mode or a different browser or just clean cached images and files (Ctrl + Shift + Del).

Having Sitecore Media Caching enabled (that stores media cache on the file system, /App_Data/MediaCache, by default) does not have the same effect as browser caching, so you should check only whether it is cached in a browser or not.

Using the code above, file's download name (Content-Disposition name ) will be the item's Display Name:

Display Name In Sitecore

File's download name is Display Name

Update: You can subscribe the handler to media:request event by using this patch:

<?xml version="1.0" encoding="utf-8"?>

<!--

Purpose: This include file implements logic to change file name to item's display name when downloading media.

It changes response Content-Disposition header.

-->
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore>    
    <events>
      <event name="media:request">        
        <handler patch:after="*[@type='Sitecore.Analytics.Media.MediaRequestEventHandler, Sitecore.Analytics']"
                 type="CustomMediaEventHandlers.ChangeFileNameEventHandler, CustomMediaEventHandlers"
                 method="OnMediaRequest" />
      </event>
    </events>
  </sitecore>
</configuration>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.