### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Constants\ConfigurationNodeNames.cs namespace xStorageService.Constants { public partial struct ConfigurationNodeNames { public const string STORAGE_SERVICE_NODE_NAME = "StorageConfiguration"; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Constants\FileExtensions.cs using xExceptions.Attributes; namespace xStorageService.Constants { public enum FileExtensions { // // Document [StringValue (".txt")] TEXT = 100, [StringValue (".pdf")] PDF = 101, [StringValue (".ppt")] PPT = 102, [StringValue (".pptx")] PPTX = 103, [StringValue (".odp")] ODP = 104, [StringValue (".pps")] PPS = 105, [StringValue (".ods")] ODS = 106, [StringValue (".xlr")] XLR = 107, [StringValue (".xls")] XLS = 108, [StringValue (".xlsx")] XLSX = 109, [StringValue (".xml")] XML = 110, [StringValue (".doc")] DOC = 111, [StringValue (".docx")] DOCX = 112, [StringValue (".odt")] ODT = 113, [StringValue (".rtf")] RTF = 114, [StringValue (".tex")] TEX = 115, [StringValue (".wpd")] WPD = 116, [StringValue (".md")] MD = 117, // // Archive [StringValue (".zip")] ZIP = 200, // // Internal Supports [StringValue (".ttf")] TTF = 300, [StringValue (".js")] JAVASCRIPT = 301, [StringValue (".css")] CSS = 302, [StringValue (".htm")] HTM = 303, [StringValue (".html")] HTML = 304, [StringValue (".sdw")] SAHER_DASHBOARD_WIDGET = 305, [StringValue (".sdwmanifest")] SAHER_DASHBOARD_WIDGET_MANIFEST = 306, // // Video [StringValue (".mp4")] MP4 = 400, [StringValue (".avi")] AVI = 401, [StringValue (".mpg")] MPG = 402, [StringValue (".mpeg")] MPEG = 403, [StringValue (".wmv")] WMV = 404, // // Audio [StringValue (".mp3")] MP3 = 500, [StringValue (".ogg")] OGG = 501, [StringValue (".wav")] WAV = 502, [StringValue (".wma")] WMA = 503, // // Image [StringValue (".png")] PNG = 600, [StringValue (".jpeg")] JPEG = 601, [StringValue (".jpg")] JPG = 602, // [StringValue (".ico")] // ICON = 603, [StringValue (".gif")] GIF = 604, [StringValue (".bmp")] BITMAP = 605, } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\DI\XDIHelperExtension.cs using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using xCommons.Extensions; using xExceptions.Constants; using xStorageService.Constants; using xStorageService.Helpers; using xStorageService.Interfaces; using xStorageService.Models; using xStorageService.Providers; namespace xStorageService.DI { public static partial class XDIHelperExtension { /// /// Retrieve XStorage Configuration from AppSettings /// /// /// public static XStorageConfiguration GetXStorageConfiguration (this IConfiguration configuration) { // var storageConfigurationSection = configuration.GetSection (ConfigurationNodeNames.STORAGE_SERVICE_NODE_NAME); return storageConfigurationSection.Get (); } /// /// Register XStorage Configuration /// /// /// public static void AddXStorageConfiguration ( this IServiceCollection services, IConfiguration configuration ) { // // Check wwwroot Folder ... if (!Directory.Exists ("wwwroot")) { Directory.CreateDirectory ("wwwroot"); } // // Retrieve and Register XStorage Configurations ... var xStorageConfiguration = configuration.GetXStorageConfiguration (); if (xStorageConfiguration.IsNull ()) { XException.InvalidConfiguration.Throw (); } // xStorageConfiguration.BaseFolder = Path.Combine (Directory.GetCurrentDirectory (), "wwwroot"); xStorageConfiguration.RootFolder = Directory.GetDirectoryRoot (xStorageConfiguration.BaseFolder); // services.AddSingleton (xStorageConfiguration); } /// /// Register XStorage Service /// /// /// public static void AddXStorageService ( this IServiceCollection services, IConfiguration configuration ) { // // Register and Retrieve XStorage Configuration services.AddXStorageConfiguration (configuration); var xStorageConfiguration = services.GetRegisteredService (); // // Add File Provider ... services.AddSingleton ( new PhysicalFileProvider (xStorageConfiguration.BaseFolder) ); // // Register XStorageHelper Service ... services.AddSingleton (); // // Register ThumbnailHelper ... services.AddSingleton (); // // Register Storage Provider ... services.AddScoped (); // // StorageService Preperation... var xStorageService = services.GetRegisteredService (); xStorageService.Prepare (); } /// /// Use XStorage Service /// /// public static void UseXStorageService (this IApplicationBuilder app) { // // Get Instance of Scope and Service and Prepare Folder Structure ... using (var scope = app.ApplicationServices.CreateScope ()) { // var storageProvider = scope.ServiceProvider.GetService (); // storageProvider.Prepare (); } // // available Static Files ... app.UseStaticFiles (); } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Helpers\XStorageHelper.cs using System; using System.IO; using System.Linq; using xCommons.Constants; using xCommons.Extensions; using xExceptions.Constants; using xStorageService.Constants; namespace xStorageService.Helpers { public partial class XStorageHelper { private int[] DocumentTypeThreshold = new int[] { 99, 307 }; private int[] ImageTypeThreshold = new int[] { 599, 606 }; private int[] AudioTypeThreshold = new int[] { 499, 504 }; private int[] VideoTypeThreshold = new int[] { 399, 405 }; public XStorageHelper () { } /// /// Retrieve FileType /// /// /// public XFileType GetType (int fileExtension) { // // Compare File Extension Integer Value and // Find Propper Type for it ... if (fileExtension > DocumentTypeThreshold[0] && fileExtension < DocumentTypeThreshold[1]) { return XFileType.Document; } else if (fileExtension > VideoTypeThreshold[0] && fileExtension < VideoTypeThreshold[1]) { return XFileType.Video; } else if (fileExtension > AudioTypeThreshold[0] && fileExtension < AudioTypeThreshold[1]) { return XFileType.Audio; } else if (fileExtension > ImageTypeThreshold[0] && fileExtension < ImageTypeThreshold[1]) { return XFileType.Image; } else { // // if not in case return Document Type return XFileType.Document; } } /// /// Retrieve a File Type /// /// /// public XFileType GetType (string fileName) { // if (fileName.IsNullOrEmpty ()) { XException.InavlidFile.Throw (); } // var ext = GetFileExtension (fileName); var extType = GetExtensionType (ext); return GetType (extType); } /// /// used for validating Extension in Widget Upload ... /// /// an string array public string[] GetAllowedExtensionsForWidgetUpload () { return new [] { FileExtensions.SAHER_DASHBOARD_WIDGET.GetStringValue () }; } /// /// Get a Files Extension string /// /// /// public string GetFileExtension (string fileName) { // // Validate Args ... if (fileName.IsNullOrEmpty ()) { return null; } // var fileExt = ""; try { fileExt = Path.GetExtension (fileName); } catch { } // return fileExt; } /// /// Get a File Name Without it's Extension /// /// /// public string GetFileNameWithoutExtension (string fileName) { // // Validate Args ... if (fileName.IsNullOrEmpty ()) { return null; } // var fileNameWithoutExt = ""; try { fileNameWithoutExt = Path .GetFileNameWithoutExtension (fileName); } catch { } // return fileNameWithoutExt; } /// /// Get File Extension Type /// /// /// public int GetExtensionType (string fileExtension) { // foreach (var extItem in Enum .GetValues (typeof (FileExtensions)) .Cast ()) { if (extItem.GetStringValue () .Contains (fileExtension.ToLower ())) { return (int) extItem; } } // return -1; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Interfaces\IXStorageProvider.cs using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.FileProviders; using xCommons.Constants; using xModels.Dtos; using xStorageService.Constants; using xStorageService.Helpers; using xStorageService.Models; namespace xStorageService.Interfaces { public partial interface IXStorageProvider { XStorageConfiguration Configuration { get; } XStorageHelper StorageHelper { get; } IFileProvider FileProvider { get; } IXThumbnailProvider ThumbnailProvider { get; } // #region Special Folders Path Getter (s) ... string GetStorageFolderPath(); string GetTempFolderPath(); string GetThumbFolderPath(); string GetUploadsFolderPath(); string GetWidgetsFolderPath(); string GetImageFolderPath(); string GetAudioFolderPath(); string GetVideoFolderPath(); string GetDocumentFolderPath(); string FilePathResolver(string fullPath); string ConvertToFileUrl(string fullPath); #endregion // #region Prepare Storage Structure ... void Prepare(); #endregion // #region Validators ... bool IsFolderExists(string path); bool IsFileExists(string filePath); bool IsSupportThumb(string fileName); bool IsSupportThumb(XFileType type); void ValidateFileExists(string filePath); void ValidateFileModel(XFileDto file); void ValidateFile(IFormFile file); void ValidateProfileImage(IFormFile file); #endregion // #region Generators ... string NewFileName(); string GenerateThumbName(string fileName); string GetNewFileName(string fileName); #endregion // #region Tools Actions ... string GetFileExtension(string fileName); string GetFileNameWithoutExtension(string fileName); FileExtensions GetFileExtensionType(string fileName); XFileType GetFileType(string fileName); XFileType GetFileType(FileExtensions fileExtension); string GetThumbnailFileFullPath(string thumFileName); string GetRelatedThumbnailFullPath(string fileName); string GetFileTypeFolderPath(XFileType type); string GetFileFolderPath( string fileName, bool isTemp = false, bool isWidget = false ); string GetFileFullPath( string fileName, bool isTemp = false, bool isWidget = false ); Task SaveFileAsync( IFormFile file, bool isTemp = false, bool isWidget = false, CancellationToken cancellationToken = default ); void DeleteFile( string fileFullPath, bool forceFileExists = true, Exception exception = null ); ICollection DeleteFiles( ICollection fileFullPaths, bool forceFileExists = true, Exception exception = null ); // Task CreateThumbnail (XFile file); Task CreateThumbnail( XFileDto file, CancellationToken cancellationToken = default ); Task CreateThumbnail( string fileName, CancellationToken cancellationToken = default ); Task HandleProfileImageSave( IFormFile file, CancellationToken cancellationToken = default ); Task HandleFileSave( IFormFile file, CancellationToken cancellationToken = default ); Task> HandleFilesSave( IFormFileCollection files, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Interfaces\IXThumbnailProvider.cs using xStorageService.Models; namespace xStorageService.Interfaces { public partial interface IXThumbnailProvider { void SetTempFolder (string folder); XImageInfo GetImageInfo (string filePath); void ResizeImage ( string filePath, string resizedFilePath, int size, int quality ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XFileResult.cs namespace xStorageService.Models { public partial class XFileResult { public string Name { get; set; } public string FileName { get; set; } public string FilePath { get; set; } public string Thmbnail { get; set; } public string ThmbnailPath { get; set; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XImageInfo.cs using ImageMagick; namespace xStorageService.Models { public partial class XImageInfo { public Interlace Interlace { get; } public int Height { get; } public MagickFormat Format { get; } public string FileName { get; } public Density Density { get; } public CompressionMethod Compression { get; } public ColorSpace ColorSpace { get; } public int Width { get; } public int Quality { get; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XStorageConfiguration.cs namespace xStorageService.Models { public partial class XStorageConfiguration { /// /// Base Path of Identity Host Server /// /// public string IdentityAuthority { get; set; } /// /// Base Path of Host Server /// /// public string Authority { get; set; } /// /// Root Directory Of File Storage /// /// public string RootFolder { get; set; } /// /// Base Root of Usable Folder for Files /// /// public string BaseFolder { get; set; } /// /// Storage Folder Label /// /// public string Storage { get; set; } /// /// Temp Folder Label /// /// public string Temp { get; set; } /// /// Thumb Folder Label /// /// public string Thumb { get; set; } /// /// Uploads Folder Label /// /// public string Uploads { get; set; } /// /// Widgets Folder Label /// /// public string Widgets { get; set; } /// /// Images Folder Label /// /// public string Image { get; set; } /// /// Audios Folder Label /// /// public string Audio { get; set; } /// /// Videos Folder Label /// /// public string Video { get; set; } /// /// Documents Folder Label /// /// public string Document { get; set; } /// /// new Files Prefix /// /// public string FilePrefix { get; set; } /// /// Thumb Files Prefix /// /// public string ThumbPrefix { get; set; } /// /// Thumbnail File Sizes /// /// public int ThumbSize { get; set; } /// /// Thumbnail File Quality /// /// public int ThumbQuality { get; set; } /// /// Max File Size /// /// public long MaxFileSize { get; set; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Providers\XStorageProvider.cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.FileProviders; using xCommons.Constants; using xCommons.Extensions; using xExceptions.Constants; using xModels.Dtos; using xStorageService.Constants; using xStorageService.Helpers; using xStorageService.Interfaces; using xStorageService.Models; namespace xStorageService.Providers { public partial class XStorageProvider : IXStorageProvider { public readonly string BasePath; private readonly XFileType[] ThumbSupprtedTypes = new XFileType[] { XFileType.Image, XFileType.CoverImage, XFileType.ProfileImasge }; public IFileProvider FileProvider { get; } public XStorageHelper StorageHelper { get; } public IXThumbnailProvider ThumbnailProvider { get; } public XStorageConfiguration Configuration { get; } public XStorageProvider( IFileProvider fileProvider, XStorageHelper storageHelper, IXThumbnailProvider thumbnailProvider, XStorageConfiguration configuration ) { // FileProvider = fileProvider; Configuration = configuration; StorageHelper = storageHelper; ThumbnailProvider = thumbnailProvider; // BasePath = Path .Combine(Directory .GetCurrentDirectory(), Configuration.BaseFolder); } // #region Special Folders Path Getter (s) ... /// /// Get Storage Folder Path /// /// public string GetStorageFolderPath() { return Path.Combine(BasePath, Configuration.Storage); } /// /// Get Temp Folder Path /// /// public string GetTempFolderPath() { return Path.Combine(GetStorageFolderPath(), Configuration.Temp); } /// /// Get Uploads Folder Path /// /// public string GetUploadsFolderPath() { return Path.Combine(GetStorageFolderPath(), Configuration.Uploads); } /// /// Get Widgets Folder Path /// /// public string GetWidgetsFolderPath() { return Path.Combine(GetStorageFolderPath(), Configuration.Widgets); } /// /// Get Thumb Folder Path /// /// public string GetThumbFolderPath() { return Path.Combine(GetUploadsFolderPath(), Configuration.Thumb); } /// /// Get Images Folder Path /// /// public string GetImageFolderPath() { return Path.Combine(GetUploadsFolderPath(), Configuration.Image); } /// /// Get Audios Folder Path /// /// public string GetAudioFolderPath() { return Path.Combine(GetUploadsFolderPath(), Configuration.Audio); } /// /// Get Videos Folder Path /// /// public string GetVideoFolderPath() { return Path.Combine(GetUploadsFolderPath(), Configuration.Video); } /// /// Get Documents Folder Path /// /// public string GetDocumentFolderPath() { return Path.Combine(GetUploadsFolderPath(), Configuration.Document); } /// /// Prepare Full Path to Use for Static Files /// /// /// public string FilePathResolver(string fullPath) { return fullPath.Replace(BasePath, ""); } /// /// Convert a File Path to Url /// /// /// public string ConvertToProfileImageUrl(string fullPath) { // var authority = !Configuration.IdentityAuthority.IsNullOrEmpty() && Configuration.IdentityAuthority.EndsWith("/") ? Configuration.IdentityAuthority.Substring(0, Configuration.IdentityAuthority.Length - 1) : Configuration.IdentityAuthority; // return $"{authority}{FilePathResolver(fullPath)}"; } /// /// Convert a File Path to Url /// /// /// public string ConvertToFileUrl(string fullPath) { // var authority = !Configuration.Authority.IsNullOrEmpty() && Configuration.Authority.EndsWith("/") ? Configuration.Authority.Substring(0, Configuration.Authority.Length - 1) : Configuration.Authority; // return $"{authority}/{FilePathResolver(fullPath)}"; } #endregion // #region Prepare Storage Structure ... /// /// Check Folder Structure of Storage Area /// and Create them if not Exists /// public void Prepare() { // try { // // Storage Folder Path Check ... if (!IsFolderExists(GetStorageFolderPath())) { Directory.CreateDirectory(GetStorageFolderPath()); } // // Temp Folder Path Check ... if (!IsFolderExists(GetTempFolderPath())) { Directory.CreateDirectory(GetTempFolderPath()); } // // Temp Folder Path Check ... if (!IsFolderExists(GetThumbFolderPath())) { Directory.CreateDirectory(GetThumbFolderPath()); } // // Widgets Folder Path Chekc ... if (!IsFolderExists(GetWidgetsFolderPath())) { Directory.CreateDirectory(GetWidgetsFolderPath()); } // // Uploads Folder Path Chekc ... if (!IsFolderExists(GetUploadsFolderPath())) { Directory.CreateDirectory(GetUploadsFolderPath()); } // // Image Folder Path Chekc ... if (!IsFolderExists(GetImageFolderPath())) { Directory.CreateDirectory(GetImageFolderPath()); } // // Music Folder Path Chekc ... if (!IsFolderExists(GetAudioFolderPath())) { Directory.CreateDirectory(GetAudioFolderPath()); } // // Video Folder Path Chekc ... if (!IsFolderExists(GetVideoFolderPath())) { Directory.CreateDirectory(GetVideoFolderPath()); } // // Document Folder Path Chekc ... if (!IsFolderExists(GetDocumentFolderPath())) { Directory.CreateDirectory(GetDocumentFolderPath()); } } catch { XException.StorageServiceInitialFailed.Throw(); } // // Set Temp Folder for Actions ... ThumbnailProvider.SetTempFolder(GetTempFolderPath()); } #endregion // #region Validators ... /// /// Detrmines a Path Exists or not /// /// /// public bool IsFolderExists(string path) { return Directory.Exists(path); } /// /// Check a File Exists or not /// /// /// public bool IsFileExists(string filePath) { return File.Exists(filePath); } /// /// Check a File Name Support Thumbnail or not /// /// /// public bool IsSupportThumb(string fileName) { // if (!fileName.StartsWith(Configuration.FilePrefix)) { XException.InavlidFile.Throw(); } // var fileType = StorageHelper.GetType(fileName); return IsSupportThumb(fileType); } /// /// Check a FileType Support Thumbnail or not /// /// /// public bool IsSupportThumb(XFileType type) { return ThumbSupprtedTypes.Contains(type); } /// /// Validate a File Exists or not /// /// public void ValidateFileExists(string filePath) { // if (!IsFileExists(filePath)) { XException.NotFound.Throw(); } } /// /// Validate a File Model with it's Related Physical File /// /// public void ValidateFileModel(XFileDto file) { // // Validate Args ... if (file == null) { XException.InvalidArgs.Throw(); } // // Retrieve Full File Path ... var fileFullPath = file.Path; if (fileFullPath.IsNullOrEmpty()) { XException.InavlidFile.Throw(); } // // Retrieve is File Exists or not ... var isPhysicalFileExists = IsFileExists(file.Path); if (!isPhysicalFileExists) { XException.NotFound.Throw(); } } /// /// Validate File for Upload /// /// public void ValidateFile(IFormFile file) { // // Validate Args ... if (file == null) { XException.InvalidArgs.Throw(); } // // Check File Size not Zero ... if (file.Length == 0) { XException.EmptyFile.Throw(); } // // Check File Max Size ... if (file.Length > Configuration.MaxFileSize) { XException.MaxFileSizeExceeded.Throw(); } } /// /// Validate a Collection of IFormFile /// /// public void ValidateFiles(IFormFileCollection files) { // // Validate Args ... if (!files.HasChild()) { XException.InvalidArgs.Throw(); } // files.ToList() .ForEach(f => ValidateFile(f)); } /// /// Validate File for Profile Image /// /// public void ValidateProfileImage(IFormFile file) { // // Check File Validation ... // since Args Checked in File Validation, there is no need to // double check it ... ValidateFile(file); // // Check File Type ... var fileType = GetFileType(file.FileName); if (fileType != XFileType.Image) { XException.UnsupportedFileType.Throw(); } } #endregion // #region Generators ... /// /// Generate New File /// /// public string NewFileName() { return Configuration.FilePrefix + Guid.NewGuid().ToString().ToLower(); } /// /// Retrieve Related Thumnail File /// /// /// public string GenerateThumbName(string fileName) { // if (!IsSupportThumb(fileName)) { XException.UnsupportedFileType.Throw(); } // return fileName.Replace(Configuration.FilePrefix, Configuration.ThumbPrefix); } /// /// Get a New FileName with Extension based on Given fileName /// /// /// public string GetNewFileName(string fileName) { // // Validate Args ... if (fileName.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // var fileExt = GetFileExtension(fileName); var newFileNameWithoutExt = NewFileName(); // // Generate New File Name ... var newFileName = string.Format("{0}{1}", newFileNameWithoutExt, fileExt); // return newFileName; } #endregion // #region Tools Actions ... /// /// Extract a FileName's Extension /// /// /// public string GetFileExtension(string fileName) { // var result = StorageHelper.GetFileExtension(fileName); if (result.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // return result; } /// /// Extract a FileName's Without it's Extension /// /// /// public string GetFileNameWithoutExtension(string fileName) { // var result = StorageHelper.GetFileNameWithoutExtension(fileName); if (result.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // return result; } /// /// Get file Extension of Specified File Name /// /// /// public FileExtensions GetFileExtensionType(string fileName) { // var fileExt = GetFileExtension(fileName); if (fileExt.IsNullOrEmpty()) { XException.InvalidData.Throw(); } // var result = StorageHelper.GetExtensionType(fileExt); if (result == -1) { XException.UnsupportedFileType.Throw(); } // return (FileExtensions)result; } /// /// Return File Type of Specific File Name /// /// /// public XFileType GetFileType(string fileName) { // var fileExtension = GetFileExtensionType(fileName); return GetFileType(fileExtension); } /// /// Return File Type of Specific Extension /// /// /// public XFileType GetFileType(FileExtensions fileExtension) { return StorageHelper.GetType((int)fileExtension); } /// /// Retrieve Full Path of thumbnail File /// /// /// public string GetThumbnailFileFullPath(string thumFileName) { // if (!thumFileName.StartsWith(Configuration.ThumbPrefix)) { XException.InavlidFile.Throw(); } // return Path.Combine(GetThumbFolderPath(), thumFileName); } /// /// Retrieve a File Thumbnail Path if Supported /// /// /// public string GetRelatedThumbnailFullPath(string fileName) { // var thumbName = GenerateThumbName(fileName); return GetThumbnailFileFullPath(thumbName); } /// /// Retrieve Special File Type's Folder Path /// /// /// public string GetFileTypeFolderPath(XFileType type) { // // Retrieve Folder Path Based on file ... switch (type) { case XFileType.Image: case XFileType.CoverImage: case XFileType.ProfileImasge: return GetImageFolderPath(); case XFileType.Audio: return GetAudioFolderPath(); case XFileType.Video: return GetVideoFolderPath(); case XFileType.Document: default: return GetDocumentFolderPath(); } } /// /// Retrieve a File's Folder path /// /// /// /// /// public string GetFileFolderPath( string fileName, bool isTemp = false, bool isWidget = false ) { // // Validate Args ... if (fileName.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // var fileType = GetFileType(fileName); // var folderPath = ""; // // if isTemp equals true // ignore file type and return Temp Folder ... if (isTemp) { folderPath = GetTempFolderPath(); } // // if isWidget equals true and isTemp equals false // ignore file type and return Widget's Folder ... if (isWidget && !isTemp) { folderPath = GetWidgetsFolderPath(); } // // if both isTemp and isWidget equals false // which is the default state, retrieve proper folder path // based on file type and return it ... if (!isTemp && !isWidget) { folderPath = GetFileTypeFolderPath(fileType); } // // Check folderPath restrict to have Value ... if (folderPath.IsNullOrEmpty()) { XException.InvalidData.Throw(); } // // return result ... return folderPath; } /// /// Retrieve a Full path of a File /// /// /// /// /// public string GetFileFullPath( string fileName, bool isTemp = false, bool isWidget = false ) { // var folderPath = GetFileFolderPath( fileName, isTemp: isTemp, isWidget: isWidget ); // if (folderPath.IsNullOrEmpty()) { XException.ActionFailed.Throw(); } // return Path.Combine(folderPath, fileName); } /// /// Save a File into Storage Based on it's Type /// /// /// /// /// /// public async Task SaveFileAsync( IFormFile file, bool isTemp = false, bool isWidget = false, CancellationToken cancellationToken = default ) { // // Validate Args ... ValidateFile(file); // // Extract and Generate required Data ... var fileName = GetNewFileName(file.FileName); var folderPath = GetFileFolderPath(file.FileName, isTemp, isWidget); var fileFullPath = Path.Combine(folderPath, fileName); // // Save File ... using (var stream = new FileStream(fileFullPath, FileMode.Create)) { // await file.CopyToAsync( stream, cancellationToken ); } // // Since all Required data can be Generated based on // a simple file Name, there is no need to return additional // data as result ... return fileName; } /// /// Delete a Physical File by Validate it's Exists /// /// /// /// public void DeleteFile( string fileFullPath, bool forceFileExists = true, Exception exception = null ) { // // Validate Args ... if (!forceFileExists && fileFullPath.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // // Prepare Default Exception ... if (exception == null) { exception = XException.NotFound.ToException(); } // // Check File Exists ... var isFileExists = File.Exists(fileFullPath); if (forceFileExists && !isFileExists) { XException.NotFound.Throw(); } // // Handle Prevent Error when forceFileExists false // and File doesn't Exists ... if (!forceFileExists && !isFileExists) { return; } // File.Delete(fileFullPath); } /// /// Remove a List of Physical Files Path /// and return Un Removable Files ... /// /// /// /// /// public ICollection DeleteFiles( ICollection fileFullPaths, bool forceFileExists = true, Exception exception = null ) { // if (exception.IsNull()) { exception = XException.NotFound.ToException(); } // var result = fileFullPaths.Where(f => !IsFileExists(GetFileFullPath(f))).ToList(); if (forceFileExists && result.HasChild()) { throw exception; } // var existsFile = fileFullPaths.Where(f => IsFileExists(f)).ToList(); existsFile.ForEach(f => { DeleteFile( f, forceFileExists: forceFileExists, exception: exception ); }); // return fileFullPaths.Except(existsFile).ToList(); } /// /// Create Thumbnail based on FileName.Ext /// /// /// /// public async Task CreateThumbnail( string fileName, CancellationToken cancellationToken = default ) { // if (fileName.IsNullOrEmpty()) { return; } // await Task.Run(() => { // var fileFullPath = GetFileFullPath(fileName); if (!IsFileExists(fileFullPath)) { XException.NotFound.Throw(); } // var thumbFileName = GenerateThumbName(fileName); var thumbFullPath = GetThumbnailFileFullPath(thumbFileName); // ThumbnailProvider.ResizeImage( fileFullPath, thumbFullPath, Configuration.ThumbSize, Configuration.ThumbQuality ); }, cancellationToken); } /// /// Create Thumbnail based on XFile model /// /// /// /// public async Task CreateThumbnail( XFileDto file, CancellationToken cancellationToken = default ) { // await CreateThumbnail( file.Name, cancellationToken ); } /// /// Save and Create a Thumbnail For Profile Image /// /// /// /// public async Task HandleProfileImageSave( IFormFile file, CancellationToken cancellationToken = default ) { // ValidateProfileImage(file); // var savedFileName = await SaveFileAsync( file, isTemp: false, isWidget: false, cancellationToken: cancellationToken ); var thumbFileName = GenerateThumbName(savedFileName); // var savedFileFullPath = GetFileFullPath(savedFileName); var thumbFullPath = GetThumbnailFileFullPath(thumbFileName); // await CreateThumbnail( savedFileName, cancellationToken ); // return new XFileResult { Name = file.Name, FileName = savedFileName, FilePath = ConvertToProfileImageUrl(savedFileFullPath), Thmbnail = thumbFileName, ThmbnailPath = ConvertToProfileImageUrl(thumbFullPath) }; } /// /// Handle File Upload with Support of Thumbnails ... /// /// /// /// public async Task HandleFileSave( IFormFile file, CancellationToken cancellationToken = default ) { // ValidateFile(file); // var savedFileName = await SaveFileAsync(file, isTemp: false, isWidget: false); // var savedFileFullPath = GetFileFullPath(savedFileName); // var thumbFileName = ""; var thumbFullPath = ""; var fileType = GetFileType(savedFileName); if (fileType.IsImageKind()) { // thumbFileName = GenerateThumbName(savedFileName); thumbFullPath = GetThumbnailFileFullPath(thumbFileName); // await CreateThumbnail(savedFileName); } // var result = new XFileResult { Name = file.FileName, FileName = savedFileName, FilePath = ConvertToFileUrl(savedFileFullPath), Thmbnail = thumbFileName, ThmbnailPath = ConvertToFileUrl(thumbFullPath), }; // return result; } /// /// Handle File Upload with Support of Thumbnails ... /// /// /// /// public async Task> HandleFilesSave( IFormFileCollection files, CancellationToken cancellationToken = default ) { // ValidateFiles(files); // var result = new Collection(); foreach (var file in files) { // var savedFileName = await SaveFileAsync( file, isTemp: false, isWidget: false, cancellationToken: cancellationToken ); // var savedFileFullPath = GetFileFullPath(savedFileName); // var thumbFileName = ""; var thumbFullPath = ""; var fileType = GetFileType(savedFileName); if (fileType.IsImageKind()) { // thumbFileName = GenerateThumbName(savedFileName); thumbFullPath = GetThumbnailFileFullPath(thumbFileName); // await CreateThumbnail( savedFileName, cancellationToken ); } // result.Add( new XFileResult { Name = file.FileName, FileName = savedFileName, FilePath = ConvertToFileUrl(savedFileFullPath), Thmbnail = thumbFileName, ThmbnailPath = ConvertToFileUrl(thumbFullPath), }); } // return result; } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Providers\XThumbnailProvider.cs using ImageMagick; using xCommons.Extensions; using xStorageService.Interfaces; using xStorageService.Models; namespace xStorageService.Providers { public partial class XThumbnailProvider : IXThumbnailProvider { public void SetTempFolder (string folder) { MagickNET.SetTempDirectory (folder); } public XImageInfo GetImageInfo (string filePath) { // MagickImageInfo info = new MagickImageInfo (filePath); return info.MapConvert (); } public void ResizeImage ( string filePath, string resizedFilePath, int size, int quality ) { // using (var image = new MagickImage (filePath)) { // image.Resize (size, size); image.Strip (); image.Quality = quality; image.Write (resizedFilePath); } } } }