1

In administration Sitecore 9.0.1, we disabled duplicate items at the same level by setting the AllowDuplicateItemNamesOnSameLevel option to false. Everything works fine, but when a user attempts to upload a picture that already exists to media library an error is displayed with wrong (too generic) message. We would like to have better error message.

I added custom processor similar as Sitecore.Pipelines.Upload.CheckSize but instead of FileTooBigForUpload method (which works from my code) I use FileCannotBeUploaded. Unfortunately this is causing some exception in UploadMediaForm.

public class CheckDuplicitySaveUploadProcessor : UploadProcessor
    {
        public void Process(UploadArgs args)
        {                                  
          foreach (string index in args.Files) {
              HttpPostedFile file = args.Files[index];
              if (string.IsNullOrEmpty(file?.FileName))
              {
                  continue;
              }     
              //args.UiResponseHandlerEx.FileTooBigForUpload(file.FileName); //this is OK
              args.UiResponseHandlerEx.FileCannotBeUploaded(file.FileName, "File  exist."); //exception
              return;              
            }
        }
    }

File too big

File cannot be uploaded

Method "ShowUploadError" not found in Sitecore.Shell.Applications.Media.UploadMedia.UploadMediaForm. (method: Sitecore.Web.UI.Sheer.ClientPage.Dispatch(String command)).

[Exception: Method "ShowUploadError" not found in Sitecore.Shell.Applications.Media.UploadMedia.UploadMediaForm. (method: Sitecore.Web.UI.Sheer.ClientPage.Dispatch(String command)).] Sitecore.Diagnostics.Error.Raise(String error, String method) +133 Sitecore.Shell.Framework.Commands.CommandManager.GetMethodCommand(String command) +1129 Sitecore.Web.UI.Sheer.ClientPage.Dispatch(String command) +35 Sitecore.Web.UI.Sheer.ClientPage.RaiseEvent() +124 Sitecore.Web.UI.Sheer.ClientPage.OnPreRender(EventArgs e) +801 System.Web.UI.Control.PreRenderRecursiveInternal() +162 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6875

But when I disassemble Sitecore.Client 11.1.0.0 I can see protected void ShowUploadError(string reason, string fileName) method defined.

using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Text;
using Sitecore.Web;
using Sitecore.Web.UI.Pages;
using Sitecore.Web.UI.Sheer;
using Sitecore.Web.UI.XmlControls;
using System;

namespace Sitecore.Shell.Applications.Media.UploadMedia
{
    /// <summary>Represents a UploadMediaForm.</summary>
    public class UploadMediaForm : DialogForm
    {
        /// <summary></summary>
        protected GenericControl ItemUri;

        /// <summary>Raises the load event.</summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> instance containing the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (Context.ClientPage.IsEvent || Context.ClientPage.IsPostBack)
                return;
            Item obj = Database.GetItem(Sitecore.Data.ItemUri.ParseQueryString(Context.ContentDatabase));
            if (obj == null)
                return;
            this.ItemUri.Attributes["value"] = obj.Uri.ToString();
        }

        /// <summary>Handles a click on the OK button.</summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <remarks>When the user clicks OK, the dialog is closed by calling
        /// the <see cref="M:Sitecore.Web.UI.Sheer.ClientResponse.CloseWindow">CloseWindow</see> method.</remarks>
        protected override void OnOK(object sender, EventArgs args)
        {
            string str = Context.ClientPage.ClientRequest.Form["File"];
            if (str == null || str.Trim().Length == 0)
            {
                SheerResponse.Alert("Specify a file to upload.", Array.Empty<string>());
            }
            else
            {
                this.OK.Disabled = true;
                this.Cancel.Disabled = true;
                Context.ClientPage.ClientResponse.Timer("StartUploading", 10);
            }
        }

        /// <summary>Shows the error.</summary>
        protected void ShowError()
        {
            SheerResponse.Alert("An error occured while uploading a file .\n\nThe reason may be that the file does not exist or the path is wrong.", Array.Empty<string>());
            this.OK.Disabled = true;
            this.Cancel.Disabled = true;
            this.OK.Disabled = false;
            this.Cancel.Disabled = false;
        }

        /// <summary>Starts the uploading.</summary>
        protected void StartUploading()
        {
            Context.ClientPage.ClientResponse.Eval("submit()");
        }

        /// <summary>Ends the uploading.</summary>
        /// <param name="id">The id.</param>
        protected void EndUploading(string id)
        {
            if (id.Length > 0 && WebUtil.GetQueryString("edit") == "1")
            {
                UrlString urlString = new UrlString("/sitecore/shell/Applications/Content Manager/default.aspx");
                urlString["fo"] = id;
                urlString["mo"] = "popup";
                urlString["wb"] = "0";
                urlString["pager"] = "0";
                urlString[State.Client.UsesBrowserWindowsQueryParameterName] = WebUtil.GetQueryString(State.Client.UsesBrowserWindowsQueryParameterName, "0");
                Context.ClientPage.ClientResponse.ShowModalDialog(urlString.ToString(), string.Equals(Context.Language.Name, "ja-jp", StringComparison.InvariantCultureIgnoreCase) ? "1115" : "955", "560");
            }
            SheerResponse.SetDialogValue(id);
            base.OnOK((object)this, EventArgs.Empty);
        }

        /// <summary>Shows the fle too bid.</summary>
        protected void ShowFileTooBig()
        {
            SheerResponse.Alert(Translate.Text("The file is too big to be uploaded.\n\nThe maximum size of a file that can be uploaded is {0}.", (object)MainUtil.FormatSize(Settings.Upload.MaximumDatabaseUploadSize)), Array.Empty<string>());
            this.OK.Disabled = true;
            this.Cancel.Disabled = true;
            this.OK.Disabled = false;
            this.Cancel.Disabled = false;
        }

        /// <summary>Shows the file too big.</summary>
        /// <param name="filename">The filename.</param>
        protected void ShowFileTooBig(string filename)
        {
            Assert.ArgumentNotNullOrEmpty(filename, nameof(filename));
            SheerResponse.Alert(Translate.Text("The file \"{0}\" is too big to be uploaded.\n\nThe maximum size of a file that can be uploaded is {1}.", (object)filename, (object)MainUtil.FormatSize(Settings.Upload.MaximumDatabaseUploadSize)), Array.Empty<string>());
            this.OK.Disabled = true;
            this.Cancel.Disabled = true;
            this.OK.Disabled = false;
            this.Cancel.Disabled = false;
        }

        /// <summary>Shows the upload error.</summary>
        /// <param name="reason">Reason.</param>
        /// <param name="fileName">File name.</param>
        protected void ShowUploadError(string reason, string fileName)
        {
            SheerResponse.Alert(Translate.Text(string.Format("The \"{0}\" file cannot be uploaded.\n {1}", (object)fileName, (object)reason)), Array.Empty<string>());
        }
    }
}
  • Do you need to have the upload file only as single upload or can you also upload multiple files at once? – Hishaam Namooya Sep 25 '18 at 21:02
  • Hi, multiple files. – Jaroslav Kubacek Sep 26 '18 at 7:22
  • So, based on the screenshot you've provided, you are using the Classic upload. You can change it by setting the Upload.Classic to false. You can find it in the Sitecore.config. – Hishaam Namooya Sep 26 '18 at 7:24
0

Following your comment, your requirement is to enable multiple file upload. Currently from the screenshot provided, it is using the Classic Upload. You can change the below setting to false to enable the flash upload.

<!--  UPLOAD CLASSIC
        Indicates if uploading runs in classic (no flash) mode.
        Default: false
-->
<setting name="Upload.Classic" value="false" />

The default value is false.

Then the code you have implemented will work except that you need to add the property ErrorText so that the tooltip, when hovering, shows the message. Also, you need to abort the pipeline, else it will continue through all the processors. Below is the code amendment

public class CheckDuplicitySaveUploadProcessor : Sitecore.Pipelines.Upload.UploadProcessor
{
    public void Process(Sitecore.Pipelines.Upload.UploadArgs args)
    {
        foreach (string index in args.Files)
        {
            HttpPostedFile file = args.Files[index];
            if (string.IsNullOrEmpty(file?.FileName))
            {
                continue;
            }

            //args.UiResponseHandlerEx.FileTooBigForUpload(file.FileName); //this is OK

            args.UiResponseHandlerEx.FileCannotBeUploaded(file.FileName, "File  exist."); //exception
            args.ErrorText = $"The file \"{file.FileName}\" already exists.";
            args.AbortPipeline();

            return;
        }
    }
}

Note that in the code, it is not checking if the file name already exist which I assume you'll implement it later.

Below is the screenshot of how the window will appear when the user hovers on the tooltip.

enter image description here

  • Hi, thanks for resposne. I tried with both values of settings Upload.Classic. args.UiResponseHandlerEx.FileCannotBeUploaded works for multiple file upload but not for single file upload. And in case of multiple file upload it use javascript alert window. (This is what we currently have as a workaround.) I think it's Sitecore bug, I will wait some time and mb I will report it. – Jaroslav Kubacek Sep 26 '18 at 9:29
0

You should use Sitecore.StringUtil.EscapeJavascriptString on the parameter values, which (besides escaping) adds surrounding quotes. Without the quotes, the parsing goes wrong and you end up with this error.

args.UiResponseHandlerEx.FileCannotBeUploaded(
    StringUtil.EscapeJavascriptString(fileName), 
    StringUtil.EscapeJavascriptString(reason));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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