This is a migrated thread and some comments may be shown as answers.

Custom FileBrowserContentProvider w/ Azure Multiple Users and Paths

1 Answer 196 Views
Editor
This is a migrated thread and some comments may be shown as answers.
DF
Top achievements
Rank 1
DF asked on 02 Nov 2015, 03:09 PM

Hi,

 We have a custom FileBrowserContentProvider set up to use Azure blob storage.  It's coded to set the Azure storage container name when it is instantiated.  What happens is when UserA opens the form with the RadEditor, it is initialized with PathA and when UserA then opens ImageManager they can work with their files.  When UserB opens the form, it is initialized with PathB and UserB opens ImageManager and they can work with their files.  But then UserA is still on the form, and re-opens ImageManager and they see UserB's files.  

 

Is there a way to implement this so that it is safe for each user, with their different paths, to use?  Preferrably without Session variables, because it's also possible for the same user to have multiple paths on different pages opened at the same time.   Thanks

 

public class ExtendedFileProvider : FileBrowserContentProvider
   {
       private string EmptyFileName = "deleteme.$$$";
       private PathPermissions fullPermissions = PathPermissions.Upload | PathPermissions.Read | PathPermissions.Delete;
       private static string _ContainerName;
       Dictionary<string, List<FileItem>> TelerikAzure_Files = new Dictionary<string, List<FileItem>>();
       Dictionary<string, List<string>> TelerikAzure_Directories = new Dictionary<string, List<string>>();
 
       public ExtendedFileProvider(string ContainerName)
       {
           _ContainerName = ContainerName;
       }
 
       //constructor must be present when overriding a base content provider class
       //you can leave it empty
       public ExtendedFileProvider(HttpContext context, string[] searchPatterns, string[] viewPaths, string[] uploadPaths, string[] deletePaths, string selectedUrl, string selectedItemTag)
           : base(context, searchPatterns, viewPaths, uploadPaths, deletePaths, selectedUrl, selectedItemTag)
       {
           LoadContainerItems();
       }
 
 
       private string Root
       {
           get
           {
               return GetAzureClient().BaseUri.ToString().TrimEnd('/') + "/" + GetTelerikContainer().Name;
           }
       }
 
 
       private void EnsureContainerExists(CloudBlobContainer container)
       {
           container.CreateIfNotExist();
           dynamic permissions = container.GetPermissions();
           permissions.PublicAccess = BlobContainerPublicAccessType.Container;
           container.SetPermissions(permissions);
       }
 
 
       /// <summary>
       /// Loads the files and folders structure and caches the result
       /// </summary>
       /// <remarks></remarks>
       private void LoadContainerItems()
       {
 
           try
           {
 
               Dictionary<string, List<FileItem>> wFiles = new Dictionary<string, List<FileItem>>();
               Dictionary<string, List<string>> wDirectories = new Dictionary<string, List<string>>();
 
               EnsureContainerExists(GetTelerikContainer());
 
               wFiles.Clear();
               wDirectories.Clear();
               BlobRequestOptions options = new BlobRequestOptions();
               options.BlobListingDetails = BlobListingDetails.All;
               options.UseFlatBlobListing = true;
 
 
               foreach (IListBlobItem blobItem in GetAzureClient().ListBlobsWithPrefix(GetTelerikContainer().Name + "/", options))
               {
                   dynamic blob = GetTelerikContainer().GetBlobReference(blobItem.Uri.ToString());
                   string wFileName = blob.Uri.ToString().Replace(Root, "").TrimStart('/');
                   string wDirectoryName = "/" + wFileName.Replace(System.IO.Path.GetFileName(wFileName), "").TrimEnd('/');
                   blob.FetchAttributes();
 
                   FileItem wFileItem = new FileItem(System.IO.Path.GetFileName(wFileName), System.IO.Path.GetExtension(wFileName), blob.Attributes.Properties.Length, wFileName, blobItem.Uri.ToString(), "", fullPermissions);
 
                   InternalOperations.CreateErrorLogFIle(wFileItem.Name);
 
                   InternalOperations.CreateErrorLogFIle(wFileItem.ToString());
 
                   if (!wFiles.ContainsKey(wDirectoryName))
                   {
                       string Path = "";
                       dynamic ParentFolder = "";
                       foreach (string wDirectory in wDirectoryName.Split('/'))
                       {
                           Path = Path.TrimEnd('/') + "/" + wDirectory;
                           if (!wDirectories.ContainsKey(Path))
                           {
                               wDirectories.Add(Path, new List<string>());
                               if (ParentFolder.Length > 0)
                               {
                                   wDirectories[ParentFolder].Add(Path);
                               }
                           }
                           ParentFolder = Path;
                       }
                       wFiles.Add(wDirectoryName, new List<FileItem>());
                   }
                   if (!(wFileItem.Name == EmptyFileName))
                   {
                       InternalOperations.CreateErrorLogFIle("3");
                       wFiles[wDirectoryName].Add(wFileItem);
                   }
               }
 
               TelerikAzure_Files = wFiles;
               TelerikAzure_Directories = wDirectories;
 
           }
           catch (Exception ex)
           {
               InternalOperations.CreateErrorLogFIle(ex.Message);
           }
       }
 
 
 
       // ''' <summary>
       //''' Gets the Azure storage name through a key in web.config AppSettings section. E.g. <add key="DataConnectionString" value="UseDevelopmentStorage=true"/>
       //''' </summary>
       //''' <returns></returns>
       //''' <remarks></remarks>
       private CloudBlobClient GetAzureClient()
       {
           CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString);
           return storageAccount.CreateCloudBlobClient();
       }
 
 
       //     ''' <summary>
       //''' Gets the container name through a key in web.config AppSettings section. E.g. <add key="TelerikContainer" value="body"/>
       //''' </summary>
       //''' <returns></returns>
       //''' <remarks></remarks>
       private CloudBlobContainer GetTelerikContainer()
       {
           var client = GetAzureClient();
           //return client.GetContainerReference(ConfigurationManager.AppSettings["TelerikContainer"].ToString());
 
           return client.GetContainerReference(_ContainerName);
       }
 
       public override string CreateDirectory(string path, string name)
       {
           string Filename = (path + name).TrimStart('/');
           Microsoft.WindowsAzure.StorageClient.CloudBlob blob = GetTelerikContainer().GetBlobReference(Filename + "/" + EmptyFileName);
           blob.UploadText(".");
 
           return string.Empty;
       }
 
 
       public override string DeleteDirectory(string path)
       {
 
 
           Microsoft.WindowsAzure.StorageClient.BlobRequestOptions options = new Microsoft.WindowsAzure.StorageClient.BlobRequestOptions();
 
           options.BlobListingDetails = BlobListingDetails.All;
           options.UseFlatBlobListing = true;
 
           foreach (IListBlobItem blobItem in GetAzureClient().ListBlobsWithPrefix(GetTelerikContainer().Name + path, options))
           {
               string wFileName = blobItem.Uri.ToString().Replace(Root, "");
               DeleteFile(wFileName);
           }
 
 
           return string.Empty;
       }
 
       public override string DeleteFile(string path)
       {
           CloudBlob blob = GetTelerikContainer().GetBlobReference(path.TrimStart('/'));
           blob.DeleteIfExists();
           //if (!BatchProcess)
           //{
           //    PurgeCacheItems("TelerikAzure_");
           //}
 
           return string.Empty;
       }
 
 
       public override System.IO.Stream GetFile(string url)
       {
           url = url.TrimStart('/');
           var blob = GetTelerikContainer().GetBlobReference(url);
           try
           {
               byte[] content = blob.DownloadByteArray();
 
               if (content.Length != 0)
               {
                   return new System.IO.MemoryStream(content);
 
               }
               return null;
           }
           catch (Exception Ex)
           {
               return null;
           }
       }
 
       public override string GetFileName(string url)
       {
           return System.IO.Path.GetFileName(url);
       }
 
       public override string GetPath(string url)
       {
           return url.Replace(GetFileName(url), "");
       }
 
       public override DirectoryItem ResolveDirectory(string path)
       {
           DirectoryItem[] directories = GetChildDirectories(path);
           string wDirectoryName = System.IO.Path.GetFileName(path);
 
           return new DirectoryItem(wDirectoryName, path, path, String.Empty, fullPermissions, GetChildFiles(path), directories);
       }
 
       public override DirectoryItem ResolveRootDirectoryAsTree(string path)
       {
           string wDirectoryName = System.IO.Path.GetFileName(path);
 
           DirectoryItem returnValue = new DirectoryItem(wDirectoryName, path, path, string.Empty, fullPermissions, GetChildFiles(path), GetChildDirectories(path));
           return returnValue;
       }
 
       public override string StoreBitmap(System.Drawing.Bitmap bitmap, string url, System.Drawing.Imaging.ImageFormat format)
       {
           dynamic blob = GetTelerikContainer().GetBlobReference(url);
           System.IO.MemoryStream imgStream = new System.IO.MemoryStream();
           if (format.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
           {
               blob.Properties.ContentType = "image/jpeg";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Gif))
           {
               blob.Properties.ContentType = "image/gif";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Png))
           {
               blob.Properties.ContentType = "image/png";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Icon))
           {
               blob.Properties.ContentType = "image/icon";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
           {
               blob.Properties.ContentType = "image/tiff";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Wmf))
           {
               blob.Properties.ContentType = "image/wmf";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Emf))
           {
               blob.Properties.ContentType = "image/emf";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Exif))
           {
               blob.Properties.ContentType = "image/exif";
           }
           else if (format.Equals(System.Drawing.Imaging.ImageFormat.Bmp) | format.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp))
           {
               blob.Properties.ContentType = "image/bmp";
           }
           bitmap.Save(imgStream, format);
 
           imgStream.Position = 0;
           blob.UploadFromStream(imgStream);
 
           imgStream.Close();
           //PurgeCacheItems("TelerikAzure_");
 
           return string.Empty;
       }
 
       public override string StoreFile(Telerik.Web.UI.UploadedFile file, string path, string name, params string[] arguments)
       {
           string Filename = (path + name).TrimStart('/');
 
           dynamic blob = GetTelerikContainer().GetBlobReference(Filename);
           blob.Properties.ContentType = file.ContentType;
           blob.UploadFromStream(file.InputStream);
           //PurgeCacheItems("TelerikAzure_");
 
           return string.Empty;
       }
 
 
       private FileItem[] GetChildFiles(string path)
       {
           Dictionary<string, List<FileItem>> wFiles = TelerikAzure_Files;
 
           try
           {
               List<FileItem> wReturn = new List<FileItem>();
               foreach (FileItem wFile in wFiles[path])
               {
                   if (IsExtensionAllowed(wFile.Extension))
                   {
                       wReturn.Add(wFile);
                   }
               }
               return wReturn.ToArray();
           }
 
           catch (Exception ex)
           {
               InternalOperations.CreateErrorLogFIle("=>>5");
               return new FileItem[] { };
           }
       }
 
 
       private bool IsExtensionAllowed(string extension)
       {
           return Array.IndexOf(SearchPatterns, "*.*") >= 0 || Array.IndexOf(SearchPatterns, "*" + extension.ToLower()) >= 0;
       }
 
       private DirectoryItem[] GetChildDirectories(string path)
       {
           Dictionary<string, List<string>> wDirectories = TelerikAzure_Directories;
 
           List<DirectoryItem> directories = new List<Telerik.Web.UI.Widgets.DirectoryItem>();
 
           try
           {
               foreach (string wDirectory in wDirectories[path])
               {
                   string wDirectoryName = System.IO.Path.GetFileName(wDirectory);
                   directories.Add(new DirectoryItem(wDirectoryName, wDirectory, wDirectory, String.Empty, fullPermissions, GetChildFiles(wDirectory), GetChildDirectories(wDirectory)));
               }
 
               return directories.ToArray();
           }
 
           catch (Exception ex)
           {
               return new DirectoryItem[] { };
           }
       }
 
       public override bool CanCreateDirectory
       {
           get { return true; }
       }
 
       //For Older Telerik Version Delete keyword "Overrides"
       public override bool CheckWritePermissions(string folderPath)
       {
           return true;
       }
 
       public override string MoveFile(string path, string newPath)
       {
           string Filename = path.TrimStart('/');
           dynamic blobSource = GetTelerikContainer().GetBlobReference(Filename);
           dynamic blobDestination = GetTelerikContainer().GetBlobReference(newPath.TrimStart('/'));
           try
           {
               blobDestination.CopyFromBlob(blobSource);
           }
           catch (Exception ex)
           {
           }
           blobSource.DeleteIfExists();
 
           return string.Empty;
       }
 
       public override string MoveDirectory(string path, string newPath)
       {
           newPath = newPath + "/";
           BlobRequestOptions options = new BlobRequestOptions();
           options.BlobListingDetails = BlobListingDetails.All;
           options.UseFlatBlobListing = true;
           foreach (IListBlobItem blobItem in GetAzureClient().ListBlobsWithPrefix(GetTelerikContainer().Name + path, options))
           {
               string wFileName = blobItem.Uri.ToString().Replace(Root, "");
               string wNewFileName = wFileName.Replace(path, newPath);
               MoveFile(wFileName, wNewFileName);
           }
 
           return string.Empty;
       }
   }

1 Answer, 1 is accepted

Sort by
0
Ianko
Telerik team
answered on 03 Nov 2015, 07:24 AM

Hello Martin,

When it comes to custom File Content Providers, it is greatly recommended to manually handle the situations encountered. Mainly, this is a framework exposed by RadFileExplorer that enables you to extend the control as per to your requirements. And the way it is implemented is strictly a general programmatic task that includes knowledge how to programmatically capture the user and configure the paths and files accordingly.

Whether session storage should be used or not is something that should be considered per case. I am unable to consult you on that as this is not related to RadEditor nor to RadFileExplorer. 

I suggest you to refer to more general, public forums  or resources regarding ASP.NET on the matter as it is not directly related to Telerik controls, but to general knowledge about handling this situation. 

Regards,

Ianko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Editor
Asked by
DF
Top achievements
Rank 1
Answers by
Ianko
Telerik team
Share this question
or