In a previous post I gave a proof of concept on a custom Content Editor Image field which gives content authors the ability to download an image from a URL and save to the downloaded image to the Media Library.
During my testing of this solution, I noticed some odd behavior where I was seeing my image being uploaded twice to the Media Library — one Media Library Item being placed in a folder selected by the user and then another being placed right under the Media Library root Item (/sitecore/media library).
At first I thought I had a bug in my code though could not track it down. I even made many attempts at refactoring the code I had, thinking I was missing something during the debugging process. Still, to no avail, the “bug” was popping its head up during my testing.
However, after a few more passes at refactoring, the “bug” magically disappeared. I figured “hey, I somehow fixed it but have no idea how. Let’s move forward on writing a blog post.”
Unfortunately, the “bug” popped up again when writing my last post. I was quite taken aback given I was repurposing most of the code from the previous solution with the “bug”, and had thought I fixed it. Trust me, I was completely baffled.
Then it dawned on me: I was using the /upload folder in those two solutions — I was placing downloaded images I retrieved from the internet via code into the /upload directory of my Sitecore instance — and remembered Sitecore had an “out of the box” feature which uploads images that are placed into the /upload directory into the Media Library automatically (btw, I remember this feature has existed since I started on Sitecore 9 years ago, so it’s been around for a while; I only forgot about it because I haven’t had any clients use it for many years). Once I changed where I was saving these images on disk, the “bug” magically disappeared.
So that mysterious and baffling — not to mention frustrating — experience brings me to this post. How does Sitecore know there is an image in the /upload directory ready to be uploaded into the Media Library?
Let me introduce you to the UploadWatcher, a Sitecore.IO.FileWatcher which lives in the Sitecore.Resources.Media namespace in Sitecore.Kernel.dll — if you don’t know what a Sitecore FileWatcher is, please see my post on what they are and how to create a custom one in Sitecore.
Like all FileWatchers in Sitecore, the UploadWatcher is defined in the Web.config under /configuration/system.webServer/modules:
You might be asking “Mike, why are these defined in the Web.config and not in a patch include configuration file?” Well, all Sitecore FileWatchers are essentially HTTP Modules and, unfortunately, that’s where they must be defined.
How does the UploadWatcher know to monitor the /upload directory in the website root of my Sitecore instance? Well, this is defined in Sitecore configuration under /configuration/sitecore/settings/setting[@name=’MediaFolder’]:
You can use a patch configuration file to change the above value if you do not want the UploadWatcher to read from the /upload directory.
The UploadWatcher instance also checks other parts of Sitecore configuration. The following configuration is used specifically by the UploadWatcher:
It appears you can also change things in the above configuration but I would suggest you don’t unless you have a good reason to do so.
The UploadWatcher also reads the following Sitecore configuration:
What’s the above configuration all about? Basically, the UploadWatcher instance loads these into a private collection on itself, and uses this collection when checking to ignore files with certain substrings in their file names. You can also include elements that define substrings in a file path to be ignored — you would do so by using <ignorepath contains=”some substring” /> elements. These elements would be siblings of the <ignore /> elements, and are read into a separate private collection on the UploadWatcher instance.
In my next post, I will give an example on how to add functionality to the UploadWatcher. Until then, keep on Sitecoring.