diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs
index a0470c2b8..314b984d4 100644
--- a/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs
+++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs
@@ -89,6 +89,8 @@ namespace Orchard.Azure.Services.FileSystems {
             return newPath;
         }
 
+        private static string GetFolderName(string path) => path.Substring(path.LastIndexOf('/') + 1);
+
         public string Combine(string path1, string path2) {
             if (path1 == null) {
                 throw new ArgumentNullException("path1");
@@ -141,10 +143,10 @@ namespace Orchard.Azure.Services.FileSystems {
             }
 
             return BlobClient.ListBlobs(prefix)
-                        .OfType<CloudBlockBlob>()
-                        .Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry))
-                        .Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot))
-                        .ToArray();
+                .OfType<CloudBlockBlob>()
+                .Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry))
+                .Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot))
+                .ToArray();
         }
 
         public IEnumerable<IStorageFolder> ListFolders(string path) {
@@ -194,6 +196,11 @@ namespace Orchard.Azure.Services.FileSystems {
 
         public void CreateFolder(string path) {
             path = ConvertToRelativeUriPath(path);
+
+            if (FileSystemStorageProvider.FolderNameContainsInvalidCharacters(GetFolderName(path))) {
+                throw new InvalidNameCharacterException("The directory name contains invalid character(s)");
+            }
+
             Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path));
 
             // Creating a virtually hidden file to make the directory an existing concept
@@ -225,6 +232,10 @@ namespace Orchard.Azure.Services.FileSystems {
             path = ConvertToRelativeUriPath(path);
             newPath = ConvertToRelativeUriPath(newPath);
 
+            if (FileSystemStorageProvider.FolderNameContainsInvalidCharacters(GetFolderName(newPath))) {
+                throw new InvalidNameCharacterException("The new directory name contains invalid character(s)");
+            }
+
             if (!path.EndsWith("/"))
                 path += "/";
 
@@ -260,6 +271,10 @@ namespace Orchard.Azure.Services.FileSystems {
             path = ConvertToRelativeUriPath(path);
             newPath = ConvertToRelativeUriPath(newPath);
 
+            if (FileSystemStorageProvider.FileNameContainsInvalidCharacters(Path.GetFileName(newPath))) {
+                throw new InvalidNameCharacterException("The new file name contains invalid character(s)");
+            }
+
             Container.EnsureBlobExists(String.Concat(_root, path));
             Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath));
 
@@ -284,6 +299,10 @@ namespace Orchard.Azure.Services.FileSystems {
         public IStorageFile CreateFile(string path) {
             path = ConvertToRelativeUriPath(path);
 
+            if (FileSystemStorageProvider.FileNameContainsInvalidCharacters(Path.GetFileName(path))) {
+                throw new InvalidNameCharacterException("The file name contains invalid character(s)");
+            }
+
             if (Container.BlobExists(String.Concat(_root, path))) {
                 throw new ArgumentException("File " + path + " already exists");
             }
@@ -371,10 +390,7 @@ namespace Orchard.Azure.Services.FileSystems {
                 _rootPath = rootPath;
             }
 
-            public string GetName() {
-                var path = GetPath();
-                return path.Substring(path.LastIndexOf('/') + 1);
-            }
+            public string GetName() => GetFolderName(GetPath());
 
             public string GetPath() {
                 return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/');
@@ -399,11 +415,12 @@ namespace Orchard.Azure.Services.FileSystems {
                 long size = 0;
 
                 foreach (var blobItem in directoryBlob.ListBlobs()) {
-                    if (blobItem is CloudBlockBlob)
-                        size += ((CloudBlockBlob)blobItem).Properties.Length;
-
-                    if (blobItem is CloudBlobDirectory)
-                        size += GetDirectorySize((CloudBlobDirectory)blobItem);
+                    if (blobItem is CloudBlockBlob blob) {
+                        size += blob.Properties.Length;
+                    }
+                    else if (blobItem is CloudBlobDirectory directory) {
+                        size += GetDirectorySize(directory);
+                    }
                 }
 
                 return size;
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs
index 8130d5e51..49c354323 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs
@@ -3,15 +3,14 @@ using System.Collections.Generic;
 using System.IO;
 using System.Web.Mvc;
 using Orchard.ContentManagement;
+using Orchard.FileSystems.Media;
+using Orchard.Localization;
+using Orchard.Logging;
+using Orchard.MediaLibrary.Models;
 using Orchard.MediaLibrary.Services;
 using Orchard.MediaLibrary.ViewModels;
 using Orchard.Themes;
 using Orchard.UI.Admin;
-using Orchard.MediaLibrary.Models;
-using Orchard.Localization;
-using System.Linq;
-using Orchard.FileSystems.Media;
-using Orchard.Logging;
 
 namespace Orchard.MediaLibrary.Controllers {
     [Admin, Themed(false)]
@@ -107,10 +106,16 @@ namespace Orchard.MediaLibrary.Controllers {
                         url = mediaPart.FileName,
                     });
                 }
-                catch (Exception ex) {
-                    Logger.Error(ex, "Unexpected exception when uploading a media.");
+                catch (InvalidNameCharacterException) {
                     statuses.Add(new {
-                        error = T(ex.Message).Text,
+                        error = T("The file name contains invalid character(s)").Text,
+                        progress = 1.0,
+                    });
+                }
+                catch (Exception ex) {
+                    Logger.Error(ex, T("Unexpected exception when uploading a media.").Text);
+                    statuses.Add(new {
+                        error = ex.Message,
                         progress = 1.0,
                     });
                 }
@@ -130,7 +135,7 @@ namespace Orchard.MediaLibrary.Controllers {
                 return HttpNotFound();
 
             // Check permission
-            if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, replaceMedia.FolderPath) && _mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, replaceMedia.FolderPath)) 
+            if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, replaceMedia.FolderPath) && _mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, replaceMedia.FolderPath))
                 && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) {
                 return new HttpUnauthorizedResult();
             }
@@ -138,7 +143,7 @@ namespace Orchard.MediaLibrary.Controllers {
             var statuses = new List<object>();
 
             var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
-            
+
             // Loop through each file in the request
             for (int i = 0; i < HttpContext.Request.Files.Count; i++) {
                 // Pointer to file
@@ -146,7 +151,8 @@ namespace Orchard.MediaLibrary.Controllers {
                 var filename = Path.GetFileName(file.FileName);
 
                 // if the file has been pasted, provide a default name
-                if (file.ContentType.Equals("image/png", StringComparison.InvariantCultureIgnoreCase) && !filename.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) {
+                if (file.ContentType.Equals("image/png", StringComparison.InvariantCultureIgnoreCase)
+                    && !filename.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) {
                     filename = "clipboard.png";
                 }
 
@@ -184,7 +190,7 @@ namespace Orchard.MediaLibrary.Controllers {
                     });
                 }
                 catch (Exception ex) {
-                    Logger.Error(ex, "Unexpected exception when uploading a media.");
+                    Logger.Error(ex, T("Unexpected exception when uploading a media.").Text);
 
                     statuses.Add(new {
                         error = T(ex.Message).Text,
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs
index b79ede9e5..9b567b1c5 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs
@@ -1,9 +1,9 @@
 using System;
 using System.IO;
 using System.Linq;
-using System.Text.RegularExpressions;
 using System.Web.Mvc;
 using Orchard.ContentManagement;
+using Orchard.FileSystems.Media;
 using Orchard.Localization;
 using Orchard.Logging;
 using Orchard.MediaLibrary.Models;
@@ -36,7 +36,7 @@ namespace Orchard.MediaLibrary.Controllers {
         public ActionResult Create(string folderPath) {
             if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath) || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, folderPath))) {
                 Services.Notifier.Error(T("Couldn't create media folder"));
-                return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary", folderPath = folderPath });
+                return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary", folderPath });
             }
 
             // If the user is trying to access a folder above his boundaries, redirect him to his home folder
@@ -68,28 +68,32 @@ namespace Orchard.MediaLibrary.Controllers {
                 return new HttpUnauthorizedResult();
             }
 
+            var failed = false;
             try {
-                bool valid = String.IsNullOrWhiteSpace(viewModel.Name) || Regex.IsMatch(viewModel.Name, @"^[^:?#\[\]@!$&'()*+,.;=\s\""\<\>\\\|%]+$");
-                if (!valid) {
-                    throw new ArgumentException(T("Folder contains invalid characters").ToString());
-                }
-                else {
-                    _mediaLibraryService.CreateFolder(viewModel.FolderPath, viewModel.Name);
-                    Services.Notifier.Information(T("Media folder created"));
-                }
+                _mediaLibraryService.CreateFolder(viewModel.FolderPath, viewModel.Name);
+                Services.Notifier.Information(T("Media folder created"));
+            }
+            catch (InvalidNameCharacterException) {
+                Services.Notifier.Error(T("The folder name contains invalid character(s)."));
+                failed = true;
             }
             catch (ArgumentException argumentException) {
                 Services.Notifier.Error(T("Creating Folder failed: {0}", argumentException.Message));
+                failed = true;
+            }
+
+            if (failed) {
                 Services.TransactionManager.Cancel();
                 return View(viewModel);
             }
+
             return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary" });
         }
 
         public ActionResult Edit(string folderPath) {
             if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath) || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, folderPath))) {
                 Services.Notifier.Error(T("Couldn't edit media folder"));
-                return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary", folderPath = folderPath });
+                return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary", folderPath });
             }
 
             if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) {
@@ -125,7 +129,7 @@ namespace Orchard.MediaLibrary.Controllers {
             var viewModel = new MediaManagerFolderEditViewModel();
             UpdateModel(viewModel);
 
-            if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, viewModel.FolderPath) 
+            if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, viewModel.FolderPath)
                 || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, viewModel.FolderPath))) {
                 return new HttpUnauthorizedResult();
             }
@@ -136,14 +140,12 @@ namespace Orchard.MediaLibrary.Controllers {
             }
 
             try {
-                bool valid = String.IsNullOrWhiteSpace(viewModel.Name) || Regex.IsMatch(viewModel.Name, @"^[^:?#\[\]@!$&'()*+,.;=\s\""\<\>\\\|%]+$");
-                if (!valid) {
-                    throw new ArgumentException(T("Folder contains invalid characters").ToString());
-                }
-                else {
-                    _mediaLibraryService.RenameFolder(viewModel.FolderPath, viewModel.Name);
-                    Services.Notifier.Information(T("Media folder renamed"));
-                }
+                _mediaLibraryService.RenameFolder(viewModel.FolderPath, viewModel.Name);
+                Services.Notifier.Information(T("Media folder renamed"));
+            }
+            catch (InvalidNameCharacterException) {
+                Services.Notifier.Error(T("The folder name contains invalid character(s)."));
+                return View(viewModel);
             }
             catch (Exception exception) {
                 Services.Notifier.Error(T("Editing Folder failed: {0}", exception.Message));
@@ -198,7 +200,7 @@ namespace Orchard.MediaLibrary.Controllers {
                 // don't try to rename the file if there is no associated media file
                 if (!string.IsNullOrEmpty(media.FileName)) {
                     // check permission on source folder
-                    if(!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, media.FolderPath)) {
+                    if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, media.FolderPath)) {
                         return new HttpUnauthorizedResult();
                     }
 
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs
index f9e58b547..f165d5955 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs
@@ -1,14 +1,14 @@
 using System;
 using Orchard.ContentManagement;
 using Orchard.ContentManagement.Drivers;
+using Orchard.FileSystems.Media;
 using Orchard.Localization;
 using Orchard.MediaLibrary.Models;
 using Orchard.MediaLibrary.Services;
 using Orchard.Security;
 using Orchard.UI.Notify;
 
-namespace Orchard.MediaLibrary.MediaFileName
-{
+namespace Orchard.MediaLibrary.MediaFileName {
     public class MediaFileNameDriver : ContentPartDriver<MediaPart> {
         private readonly IAuthenticationService _authenticationService;
         private readonly IAuthorizationService _authorizationService;
@@ -58,6 +58,8 @@ namespace Orchard.MediaLibrary.MediaFileName
                         var priorFileName = model.FileName;
                         if (updater.TryUpdateModel(model, Prefix, null, null)) {
                             if (model.FileName != null && !model.FileName.Equals(priorFileName, StringComparison.OrdinalIgnoreCase)) {
+                                var fieldName = "MediaFileNameEditorSettings.FileName";
+
                                 try {
                                     _mediaLibraryService.RenameFile(part.FolderPath, priorFileName, model.FileName);
                                     part.FileName = model.FileName;
@@ -65,14 +67,18 @@ namespace Orchard.MediaLibrary.MediaFileName
                                     _notifier.Add(NotifyType.Information, T("File '{0}' was renamed to '{1}'", priorFileName, model.FileName));
                                 }
                                 catch (OrchardException) {
-                                    updater.AddModelError("MediaFileNameEditorSettings.FileName", T("Unable to rename file. Invalid Windows file path."));
+                                    updater.AddModelError(fieldName, T("Unable to rename file. Invalid Windows file path."));
                                 }
-                                catch (Exception) {
-                                    updater.AddModelError("MediaFileNameEditorSettings.FileName", T("Unable to rename file"));
+                                catch (InvalidNameCharacterException) {
+                                    updater.AddModelError(fieldName, T("The file name contains invalid character(s)."));
+                                }
+                                catch (Exception exception) {
+                                    updater.AddModelError(fieldName, T("Unable to rename file: {0}", exception.Message));
                                 }
                             }
                         }
                     }
+
                     return model;
                 });
         }
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs
index 349469205..abadaff3a 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs
@@ -6,13 +6,13 @@ using System.Web;
 using Orchard.ContentManagement;
 using Orchard.ContentManagement.MetaData.Models;
 using Orchard.Core.Common.Models;
+using Orchard.Core.Title.Models;
 using Orchard.FileSystems.Media;
 using Orchard.Localization;
 using Orchard.MediaLibrary.Factories;
 using Orchard.MediaLibrary.Models;
-using Orchard.Core.Title.Models;
-using Orchard.Validation;
 using Orchard.MediaLibrary.Providers;
+using Orchard.Validation;
 
 namespace Orchard.MediaLibrary.Services {
     public class MediaLibraryService : IMediaLibraryService {
@@ -21,7 +21,6 @@ namespace Orchard.MediaLibrary.Services {
         private readonly IStorageProvider _storageProvider;
         private readonly IEnumerable<IMediaFactorySelector> _mediaFactorySelectors;
         private readonly IMediaFolderProvider _mediaFolderProvider;
-        private static char[] HttpUnallowed = new char[] { '<', '>', '*', '%', '&', ':', '\\', '?', '#' };
 
         public MediaLibraryService(
             IOrchardServices orchardServices,
@@ -145,12 +144,6 @@ namespace Orchard.MediaLibrary.Services {
         }
 
         public string GetUniqueFilename(string folderPath, string filename) {
-
-            // remove any char which is unallowed in an HTTP request
-            foreach (var unallowedChar in HttpUnallowed) {
-                filename = filename.Replace(unallowedChar.ToString(), "");
-            }
-
             // compute a unique filename
             var uniqueFilename = filename;
             var index = 1;
@@ -177,9 +170,9 @@ namespace Orchard.MediaLibrary.Services {
             var mediaFile = BuildMediaFile(relativePath, storageFile);
 
             using (var stream = storageFile.OpenRead()) {
-                var mediaFactory = GetMediaFactory(stream, mimeType, contentType);
-                if (mediaFactory == null)
-                    throw new Exception(T("No media factory available to handle this resource.").Text);
+                var mediaFactory = GetMediaFactory(stream, mimeType, contentType)
+                    ?? throw new Exception(T("No media factory available to handle this resource.").Text);
+
                 var mediaPart = mediaFactory.CreateMedia(stream, mediaFile.Name, mimeType, contentType);
                 if (mediaPart != null) {
                     mediaPart.FolderPath = relativePath;
@@ -256,7 +249,7 @@ namespace Orchard.MediaLibrary.Services {
             if (_orchardServices.Authorizer.Authorize(Permissions.ManageMediaContent)) {
                 return true;
             }
-            if (_orchardServices.WorkContext.CurrentUser==null)
+            if (_orchardServices.WorkContext.CurrentUser == null)
                 return _orchardServices.Authorizer.Authorize(permission);
             // determines the folder type: public, user own folder (my), folder of another user (private)
             var rootedFolderPath = this.GetRootedFolderPath(folderPath) ?? "";
@@ -268,7 +261,7 @@ namespace Orchard.MediaLibrary.Services {
                 isMyfolder = true;
             }
 
-            if(isMyfolder) {
+            if (isMyfolder) {
                 return _orchardServices.Authorizer.Authorize(Permissions.ManageOwnMedia);
             }
             else { // other
diff --git a/src/Orchard/Exceptions/DefaultExceptionPolicy.cs b/src/Orchard/Exceptions/DefaultExceptionPolicy.cs
index db6de3559..08e7466e7 100644
--- a/src/Orchard/Exceptions/DefaultExceptionPolicy.cs
+++ b/src/Orchard/Exceptions/DefaultExceptionPolicy.cs
@@ -34,7 +34,7 @@ namespace Orchard.Exceptions {
                 return false;
             }
 
-            if (sender is IEventBus &&  exception is OrchardFatalException) {
+            if (sender is IEventBus && exception is OrchardFatalException) {
                 return false;
             }
 
@@ -49,7 +49,7 @@ namespace Orchard.Exceptions {
         }
 
         private static bool IsFatal(Exception exception) {
-            return 
+            return
                 exception is OrchardSecurityException ||
                 exception is StackOverflowException ||
                 exception is AccessViolationException ||
diff --git a/src/Orchard/Exceptions/ExceptionExtensions.cs b/src/Orchard/Exceptions/ExceptionExtensions.cs
index a66ba1a8b..534c77406 100644
--- a/src/Orchard/Exceptions/ExceptionExtensions.cs
+++ b/src/Orchard/Exceptions/ExceptionExtensions.cs
@@ -1,11 +1,8 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Orchard.Security;
-using System.Threading;
-using System.Security;
 using System.Runtime.InteropServices;
+using System.Security;
+using System.Threading;
+using Orchard.Security;
 
 namespace Orchard.Exceptions {
     public static class ExceptionExtensions {
diff --git a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
index ab0abfd26..34a7b5055 100644
--- a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
+++ b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
@@ -4,15 +4,22 @@ using System.IO;
 using System.Linq;
 using System.Web.Hosting;
 using Orchard.Environment.Configuration;
-using Orchard.Localization;
-using Orchard.Validation;
 using Orchard.Exceptions;
+using Orchard.Localization;
+using Orchard.Utility.Extensions;
+using Orchard.Validation;
 
 namespace Orchard.FileSystems.Media {
     public class FileSystemStorageProvider : IStorageProvider {
         private readonly string _storagePath; // c:\orchard\media\default
         private readonly string _virtualPath; // ~/Media/Default/
         private readonly string _publicPath; // /Orchard/Media/Default/
+        public static readonly char[] HttpUnallowedCharacters =
+            new char[] { '<', '>', '*', '%', '&', ':', '\\', '/', '?', '#', '"', '{', '}', '|', '^', '[', ']', '`' };
+        public static readonly char[] InvalidFolderNameCharacters =
+            Path.GetInvalidPathChars().Union(HttpUnallowedCharacters).ToArray();
+        public static readonly char[] InvalidFileNameCharacters =
+            Path.GetInvalidFileNameChars().Union(HttpUnallowedCharacters).ToArray();
 
         public FileSystemStorageProvider(ShellSettings settings) {
             var mediaPath = HostingEnvironment.IsHosted
@@ -27,7 +34,7 @@ namespace Orchard.FileSystems.Media {
                 appPath = HostingEnvironment.ApplicationVirtualPath;
             }
             if (!appPath.EndsWith("/"))
-                appPath = appPath + '/';
+                appPath += '/';
             if (!appPath.StartsWith("/"))
                 appPath = '/' + appPath;
 
@@ -39,21 +46,21 @@ namespace Orchard.FileSystems.Media {
 
         public Localizer T { get; set; }
 
-        public int MaxPathLength {
-            get; set;
-            // The public setter allows injecting this from Sites.MyTenant.Config or Sites.config, by using
-            // an AutoFac component:
-            /*
-             <component instance-scope="per-lifetime-scope"
-                type="Orchard.FileSystems.Media.FileSystemStorageProvider, Orchard.Framework"
-                service="Orchard.FileSystems.Media.IStorageProvider">
+        /// <summary>
+        /// The public setter allows injecting this from Sites.MyTenant.Config or Sites.config, by using an AutoFac
+        /// component. See the example below.
+        /// </summary>
+        /*
+         <component
+            instance-scope="per-lifetime-scope"
+            service="Orchard.FileSystems.Media.IStorageProvider"
+            type="Orchard.FileSystems.Media.FileSystemStorageProvider, Orchard.Framework">
                 <properties>
                     <property name="MaxPathLength" value="500" />
                 </properties>
             </component>
-
-             */
-        }
+         */
+        public int MaxPathLength { get; set; }
 
         /// <summary>
         /// Maps a relative path into the storage path.
@@ -215,6 +222,12 @@ namespace Orchard.FileSystems.Media {
         /// <param name="path">The relative path to the folder to be created.</param>
         /// <exception cref="ArgumentException">If the folder already exists.</exception>
         public void CreateFolder(string path) {
+            // We are dealing with a folder here, but GetFileName returns the last path segment, which in this case is
+            // the folder name.
+            if (FolderNameContainsInvalidCharacters(Path.GetFileName(path))) {
+                throw new InvalidNameCharacterException(T("The directory name contains invalid character(s)").ToString());
+            }
+
             DirectoryInfo directoryInfo = new DirectoryInfo(MapStorage(path));
             if (directoryInfo.Exists) {
                 throw new ArgumentException(T("Directory {0} already exists", path).ToString());
@@ -248,6 +261,12 @@ namespace Orchard.FileSystems.Media {
                 throw new ArgumentException(T("Directory {0} does not exist", oldPath).ToString());
             }
 
+            // We are dealing with a folder here, but GetFileName returns the last path segment, which in this case is
+            // the folder name.
+            if (FolderNameContainsInvalidCharacters(Path.GetFileName(newPath))) {
+                throw new InvalidNameCharacterException(T("The new directory name contains invalid character(s)").ToString());
+            }
+
             DirectoryInfo targetDirectory = new DirectoryInfo(MapStorage(newPath));
             if (targetDirectory.Exists) {
                 throw new ArgumentException(T("Directory {0} already exists", newPath).ToString());
@@ -313,6 +332,10 @@ namespace Orchard.FileSystems.Media {
                 throw new ArgumentException(T("File {0} does not exist", oldPath).ToString());
             }
 
+            if (FileNameContainsInvalidCharacters(Path.GetFileName(newPath))) {
+                throw new InvalidNameCharacterException(T("The new file name contains invalid character(s)").ToString());
+            }
+
             FileInfo targetFileInfo = new FileInfo(MapStorage(newPath));
             if (targetFileInfo.Exists) {
                 throw new ArgumentException(T("File {0} already exists", newPath).ToString());
@@ -342,6 +365,10 @@ namespace Orchard.FileSystems.Media {
         /// <exception cref="ArgumentException">If the file already exists.</exception>
         /// <returns>The created file.</returns>
         public IStorageFile CreateFile(string path) {
+            if (FileNameContainsInvalidCharacters(Path.GetFileName(path))) {
+                throw new InvalidNameCharacterException(T("The file name contains invalid character(s)").ToString());
+            }
+
             FileInfo fileInfo = new FileInfo(MapStorage(path));
             if (fileInfo.Exists) {
                 throw new ArgumentException(T("File {0} already exists", fileInfo.Name).ToString());
@@ -427,6 +454,12 @@ namespace Orchard.FileSystems.Media {
             return (di.Attributes & FileAttributes.Hidden) != 0;
         }
 
+        public static bool FolderNameContainsInvalidCharacters(string folderName) =>
+            folderName.IndexOfAny(InvalidFolderNameCharacters) > -1;
+
+        public static bool FileNameContainsInvalidCharacters(string fileName) =>
+            fileName.IndexOfAny(InvalidFileNameCharacters) > -1;
+
         #endregion
 
         private class FileSystemStorageFile : IStorageFile {
diff --git a/src/Orchard/FileSystems/Media/IStorageProvider.cs b/src/Orchard/FileSystems/Media/IStorageProvider.cs
index 39501cdaa..b7d771e6b 100644
--- a/src/Orchard/FileSystems/Media/IStorageProvider.cs
+++ b/src/Orchard/FileSystems/Media/IStorageProvider.cs
@@ -128,7 +128,7 @@ namespace Orchard.FileSystems.Media {
         void SaveStream(string path, Stream inputStream);
 
         /// <summary>
-        /// Combines to paths.
+        /// Combines two paths.
         /// </summary>
         /// <param name="path1">The parent path.</param>
         /// <param name="path2">The child path.</param>
diff --git a/src/Orchard/FileSystems/Media/InvalidNameCharacterException.cs b/src/Orchard/FileSystems/Media/InvalidNameCharacterException.cs
new file mode 100644
index 000000000..53fcff0c5
--- /dev/null
+++ b/src/Orchard/FileSystems/Media/InvalidNameCharacterException.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace Orchard.FileSystems.Media {
+    public class InvalidNameCharacterException : ArgumentException {
+        public InvalidNameCharacterException(string message) : base(message) { }
+    }
+}
diff --git a/src/Orchard/FileSystems/Media/StorageProviderExtensions.cs b/src/Orchard/FileSystems/Media/StorageProviderExtensions.cs
index 8380b7645..1a5e4bf96 100644
--- a/src/Orchard/FileSystems/Media/StorageProviderExtensions.cs
+++ b/src/Orchard/FileSystems/Media/StorageProviderExtensions.cs
@@ -1,9 +1,5 @@
 using System;
-using System.Collections.Generic;
 using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Orchard.FileSystems.Media {
     public static class StorageProviderExtensions {
diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj
index a24d2a5fa..57312d77f 100644
--- a/src/Orchard/Orchard.Framework.csproj
+++ b/src/Orchard/Orchard.Framework.csproj
@@ -45,7 +45,6 @@
     <CodeAnalysisRuleSet>..\OrchardBasicCorrectness.ruleset</CodeAnalysisRuleSet>
     <Prefer32Bit>false</Prefer32Bit>
     <UseVSHostingProcess>false</UseVSHostingProcess>
-    <NoWarn></NoWarn>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -159,6 +158,7 @@
     <Compile Include="Data\Migration\Schema\DropUniqueConstraintCommand.cs" />
     <Compile Include="Environment\Extensions\Models\LifecycleStatus.cs" />
     <Compile Include="Environment\ShellBuilders\ICompositionStrategy.cs" />
+    <Compile Include="FileSystems\Media\InvalidNameCharacterException.cs" />
     <Compile Include="Mvc\ModelBinders\BooleanBinderProvider.cs" />
     <Compile Include="Mvc\Updater.cs" />
     <Compile Include="Recipes\Models\ConfigurationContext.cs" />