Blazor FileManager full example

Hi,

Thank you for your support.
Your component is great, but its documentation is insufficient.

I need an example with the following features:
-Ability to dynamically change the root folder
-Ability to use the loaded, modified or deleted file: 
   * In upload case, create a record in a table.
   * if modified, modify a row in a table. 
   * If deleted, delete a record from a table.
-Ability to add custom item in the context menu and the toolbar, and do an operation behind them (display a preview for example)
-If it is possible, create an image of the first page of the loaded file other than image (pdf, docx,..), and use it as the file icon.
-Possibility to filter the files by user and to display only the files which he has the right to see.

Thank you.

8 Replies

SP Sowmiya Padmanaban Syncfusion Team March 16, 2020 12:18 PM UTC

Hi aitlahmid,  
 
Query1 - Dynamically change the root folder 
 
If you want to dynamically change the root folder name. In FileManager component, we have provided a rootAliasName property. Using this property, you can change the root folder name. Refer the below code snippet. 
 
<EjsFileManager RootAliasName="Root Folder"> 
    <FileManagerAjaxSettings Url="/api/Default/SQLFileOperations" 
                             GetImageUrl="/api/Default/SQLGetImage" 
                             UploadUrl="/api/Default/SQLUpload" 
                             DownloadUrl="/api/Default/SQLDownload"> 
    </FileManagerAjaxSettings> 
</EjsFileManager> 
 
If we misunderstand your requirement. Can you please share the additional details regarding your requirement. It will helpful for us to resolve your issue at earlier. 
1.      If your requirement is to change the root folder based on user. 
2.      Prevent the user to viewing the particular files. 
3.      Can you please share the details, if you are using SQL File Provider 
 
To more about the FileProvider in FileManager component. Refer the below link. 
 
Query 2 – Table structure. 
 
We suspect that your requirement is to save the upload, delete and modified details in a table. In FileManager component, we have provided a support for SQL Database provider. When you have performed any operation in FileManager component (edit, rename, delete) , the changes will be reflected in your database. For instance (deleting a file in File Manager, will delete that file record from the Database). 
 
Query3 - Add custom item in the context menu and the toolbar 
 
Yes, it is possible to add the custom item in toolbar and contextmenu of FileManager component. 
 
Custom item in Toolbar – You can add the custom toolbar items using FileManagerToolbarSettings. ToolBarItemClicked() event is triggered for clicking the toolbar items. You can perform the operation based on your requirement using that event. Refer the below code snippet. 
 
<EjsFileManager RootAliasName="Root Folder"> 
        <FileManagerEvents ToolbarItemClicked="toolbarClick"></FileManagerEvents> 
        <FileManagerToolbarSettings Items="@ToolbarItems"></FileManagerToolbarSettings> 
</EjsFileManager> 
public string[] ToolbarItems =  new string[] {"NewFolder", "Upload", "Delete", "Download", "Rename", "SortBy", "Refresh", "Selection", "View", "Details", "Custom"}; 
    public void toolbarClick(ToolbarClickEventArgs args) 
    { 
        if(args.Item.Text == "Custom") 
        { 
           // Perform the operation based on your requirement. 
            System.Diagnostics.Debug.Write("Custom item clicked"); 
        } 
    } 
 
 
Custom item in Contextmenu - You can add the custom context menu items using FileManagerContextMenuSettings. OnMenuClick() event is triggered for clicking the context menu items. You can perform the operation based on your requirement using that event. Refer the below code snippet. 
 
<EjsFileManager RootAliasName="Root Folder"> 
        <FileManagerEvents ToolbarItemClicked="toolbarClick" OnMenuClick="menuClick"></FileManagerEvents           <FileManagerContextMenuSettings File="@Items" Folder="@Items"></FileManagerContextMenuSettings> 
   </EjsFileManager> 
public string[] Items = new string[] { "Open", "|", "Delete", "Download", "Rename", "|", "Details", "Custom" }; 
public void menuClick(MenuClickEventArgs args) 
    { 
        if(args.Item.Text == "Custom") 
        { 
            // Perform the operation based on your requirement. 
            System.Diagnostics.Debug.Write("Custom item clicked"); 
        } 
    } 
 
 
 
Query 4 - Create an image of the first page of the loaded file other than image (pdf, docx,..) 
 
Could you please share us following additional details regarding this requirement?. 
 
·       Are you using SQL File provider service with File Manager component? If no, then share us details regarding it. 
·       Are you expecting to the load the (PDF, DOCX) files from the SQL database to the File Manager and expecting to load the first page of the file from that SQL database location?. 
 
Once, you confirm with this details, we will check the feasibility for achieving this requirement with File Manager and update you with details on achieving this requirement. 
 
Query 5 – Access control support. 
 
We have checked your reported query that restrict the files based on user. Currently, we have not provided support for access control in SQL File provider. We have already consider this as a feature from our end. This feature will be included in any one of our upcoming release. Please be patience, until then. 
 
Track the below link for feedback status. 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 
 
 




AI aitlahmid March 18, 2020 01:38 PM UTC

Hi,

Thank you for your response. But, The proposed solutions don't solves the problems.

I use local service as Provider. If the use of the Sql File Provider is mandatory to solve these problems (especially queries 2 and 4), please tell me.

I'll explain my scenario to you:

Query1:
I have 3 options in the application menu, option1, option2 and option3. If the user chooses option1, root = 'wwwroot \ Files \ Option1'. If he chooses option2, root = 'wwwroot \ Files \ Option2' ... etc.

Query2:
I need to have the hand to add code in the events related to the operations Upload, Modification, Displacement, deletion of files.

Query3:
I need a complete example to have infos of the selected files when executing the Custom action (the 'FileDetails' property)

Thank you.


SP Sowmiya Padmanaban Syncfusion Team March 20, 2020 04:31 AM UTC

Hi Aitlahmid,  
 
Query 1 - Dynamically change the root folder 
 
Yes, you can dynamically change the root folder. You can set the root folder based on user id in controller side.  Refer the below code snippet.  
 
public class DefaultController : Controller 
    { 
        public PhysicalFileProvider operation; 
        public string basePath; 
        // Based on Login id. 
        if(option1 == "user1") { 
            string root = "wwwroot\\Files"; 
         } 
        else if(option1 == "user2") { 
          string root = "wwwroot\\Files\\Data"; 
       } 
  } 
 
Query 2 – Modify the filemanager operations. 
 
Yes, you can modify the filemanager operation based on your requirement in controller side using local service. There is no need for SQL File provider. In each operations performs controller side event is triggered. You can customize the operations inside the Models/PhysicalFileProvider.cs file. 
 
Refer the below screenshot. 
 
 
 
Query 3 – Custom action details. 
 
Yes, you can get the selected files details in SelectedFiles() method of FileManager component. Refer the below code snippet. 
 
   public async Task menuClick(MenuClickEventArgs args) 
    { 
        if(args.Item.Text == "Custom") 
        { 
            var selectedFiles = await file.GetSelectedFiles(); 
            // Perform the operation based on your requirement. 
            System.Diagnostics.Debug.WriteLine("Custom item clicked"); 
        } 
    } 
 
Query 4 – Image of pdf, docx in files. 
 
We have consider this as a custom sample from our end. We will provided  a sample within three business days. 
 
Query 5 – Access control. 
 
In FileManager component, we have provided a access control support for particular files in Physical File Provider. Refer the below code snippet to restrict the access for particular files or folder. 
 
  public DefaultController (IHostingEnvironment hostingEnvironment) 
        { 
            // You can set rules for folder access. 
            this.operation.SetRules(GetRules()); 
        } 
  public AccessDetails GetRules() 
        { 
            AccessDetails accessDetails = new AccessDetails(); 
 
            List folderRule = new List { 
                // For Default User          
                new AccessRule { Path = "/Documents", Role = "Document Manager", Read = Permission.Deny, Write = Permission.Deny, Copy = Permission.Allow, WriteContents = Permission.Allow, Upload = Permission.Allow, Download = Permission.Deny }, 
            }; 
            accessDetails.AccessRules = folderRule; 
            accessDetails.Role = "Document Manager"; 
            return accessDetails; 
        } 
 
Refer the below sample link for your reference. 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 



AI aitlahmid March 20, 2020 12:15 PM UTC

Hi,

Thank you for your response. But the sample project dosen't work as expected: folders duplicated, a lot of javascript errors,...

For Query 1, my scenario is the possibility to change the fileManager root according to the function chosen by the user in the navigation menu.If the user chooses option1, root = 'wwwroot \ Files \ Option1'. If he chooses option2, root = 'wwwroot \ Files \ Option2' ... etc.

If the SQL Provider is better then the others providers to solve my querys, please provide me an exemple based on this provider. with possibility to add columns to tables.

Thank you.


SP Sowmiya Padmanaban Syncfusion Team March 25, 2020 12:03 PM UTC

Hi Aitlahmid, 
 
Query 2  - Add additional column to the table. 
 
As per our promised, we have prepared a custom sample based on your requirement. In this sample, we have added a ReviewNumber as a additional column and display the column in DetailsView of FileManager component. 
 
If you want to display the reviewNumber column in DetailsView, you can override the getFiles method. Refer the below code snippet. 
 
public object getFiles(FileManagerDirectoryContent args) 
        { 
            FileResponse readResponse = new FileResponse(); 
            try 
            { 
               // Get the Files details of all the files in FileManager component. 
                var value = this.operation.GetFiles(args.Path, args.ShowHiddenItems, args.Data); 
                DirectoryContent cwd = new DirectoryContent(); 
                readResponse.CWD = JsonConvert.DeserializeObject<DirectoryContent>(JsonConvert.SerializeObject(value.CWD)); 
                SqlConnection sqlConnection = new SqlConnection(this.operation.ConnectionString); 
                try 
                { 
                    sqlConnection.Open(); 
                     // add the ReviewNumber column to the response. 
                    readResponse.CWD.ReviewNumber = value.CWD.Id; 
                } 
                catch (SqlException ex) { Console.WriteLine(ex.ToString()); } 
                finally { sqlConnection.Close(); } 
                readResponse.Files = JsonConvert.DeserializeObject<IEnumerable<DirectoryContent>>(JsonConvert.SerializeObject(value.Files)); 
             // add the ReviewNumber field to the each files and folder. 
                foreach (DirectoryContent file in readResponse.Files) 
                { 
                    SqlConnection sqlConnection1 = new SqlConnection(this.operation.ConnectionString); 
                    try 
                    { 
                        sqlConnection1.Open(); 
                        file.ReviewNumber = file.ReviewNumber; 
                    } 
                    catch (SqlException ex) { Console.WriteLine(ex.ToString()); } 
                    finally { sqlConnection1.Close(); } 
 
                } 
                readResponse.Details = value.Details; 
                readResponse.Error = value.Error; 
               // Return the Read response to the FileManager component. 
                return readResponse; 
            } 
            catch (SqlException ex) { return null; } 
       } 
 
And also add the ReviewNumber attribute in GetFiles method inside the SQLProvider.cs file in model folder. 
  try 
     { 
        ... 
          ... 
 
            { 
              ReviewNumber = reader["ReviewNumber"].ToString(), 
             HasChild = (bool)reader["HasChild"] 
              }; 
                     ... 
                     ... 
                while (reader.Read()) 
                { 
                    var childFiles = new FileManagerDirectoryContent 
                    { 
                        ReviewNumber = reader["ReviewNumber"].ToString(), 
                        Id = reader["ItemID"].ToString() 
                    }; 
                     ... 
                     ... 
                    files.Add(childFiles); 
                } 
           } 
 
To display the Column(ReviewNumber) in FileManager component, add the extra column in DetailsView settings (Index.razor) 
 
<SfFileManager RootAliasName="Root Folder"> 
   <FileManagerDetailsViewSettings > 
       <FileManagerColumns> 
          <FileManagerColumn Field="name" HeaderText="FileName"></FileManagerColumn> 
           <FileManagerColumn Field="dateModified" HeaderText="Date Modified"> 
            </FileManagerColumn> 
            <FileManagerColumn Field="reviewNumber" HeaderText="ReviewNumber">            
            </FileManagerColumn> 
         </FileManagerColumns> 
    </FileManagerDetailsViewSettings> 
 </SfFileManager> 
 
 
Refer the below screenshot. 
 
 
Refer the sample link below. 
 
Note: It is mandatory to add the custom column in SQL Tables. 
 
Query 1 &3  - Change Root folder and Extract pdf icon. 
 
Currently, we have preparing the sample based on your requirement. We will update the sample to you within 4 business days (31/3/2020). 
 
Please let us know, if you have any concerns. 
 
Regards,  
Sowmiya.P 



SP Sowmiya Padmanaban Syncfusion Team March 30, 2020 10:43 AM UTC

Hi Aitlahmid, 
 
Query 1 – Change the root folder. 
 
We have prepared a sample based on your requirement (Change the Root folder based on menu items). In FileManager component, you can pass the value using OnSend event. 
 
When select the items in DropDownList, you have to refresh the FileManager component.  In that case, OnSend event is triggered. 
    <SfDropDownList @ref="Dropdown" Value="@dropValue" TValue="string" TItem="Games" Placeholder="Select a game" DataSource="@LocalData"> 
        <DropDownListEvents TValue="string" ValueChange="change"></DropDownListEvents> 
        <DropDownListFieldSettings Value="ID" Text="Text"></DropDownListFieldSettings> 
    </SfDropDownList> 
    public void change(ChangeEventArgs<string> args) 
    { 
        // Refresh the FileManager component. It Triggers the onSend event in FileManager component. 
        this.Filemanager.Refresh(); 
    } 
 
Refer the below code snippet for OnSend event. 
 
<SfFileManager @ref="Filemanager"> 
    <FileManagerEvents OnSend="send"></FileManagerEvents>   
</SfFileManager>    
public void send(BeforeSendEventArgs args) 
    { 
        // Add the extra column in AhaxSettings of Filemanager and send the value to the FileManager component. 
        string AjaxSettingsString = JsonConvert.SerializeObject(args.AjaxSettings); 
        Dictionary<string, dynamic> AjaxSettings = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(AjaxSettingsString); 
        string dataString = AjaxSettings["data"]; 
        Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(dataString); 
        // Fetch the DropDown value. 
        var Option = this.Dropdown.Value; 
        data.Add("Option", Option); 
        string modifiedDataString = JsonConvert.SerializeObject(data); 
        AjaxSettings["data"] = modifiedDataString; 
        string returnString = JsonConvert.SerializeObject(AjaxSettings); 
        args.AjaxSettings = JsonConvert.DeserializeObject<object>(returnString); 
    } 
 
You can fetch the value in controller side and then set the RootFolder based on your option.  
 
 
 
[Route("SQLFileOperations")] 
        public object SQLFileOperations([FromBody] FileManagerDirectoryContent1 args) 
        { 
            if(args.Option == "Option1") 
            { 
                operation.SetSQLConnection("FileManagerConnection", "Product", "0"); 
            } 
            else if(args.Option == "Option2") { 
                // Set the path based on your requirement. 
                 
            } 
} 
 
In the below sample, we have rendering the FileManager component based on the DropDownList value. 
https://www.syncfusion.com/downloads/support/directtrac/general/ze/BlazorApp1-41556190.zip                                                                                                                                         
 
Query 2- Extract the Pdf and excel files. 
 
You can import the below package in your application for extracting the word, excel and pdf files. 
 
Syncfusion.DocIORenderer.Net.Core 
Syncfusion.Blazor.PdfViewerServer.Windows 
Syncfusion.PresentationRenderer.Net.Core 
 
We have prepared a sample in Physical file provider. You can change the icon using OnFileLoad event. Refer the below code snippet for Client side function. 
 
  public async void fileLoad(FileLoadEventArgs args) 
    { 
        string dataString = JsonConvert.SerializeObject(args.FileDetails); 
        Dictionary<string, dynamic> fileDetails = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(dataString); 
        if (args.Module == "LargeIconsView"  && (fileDetails["type"] == ".pptx" || fileDetails["type"] == ".docx" 
    || fileDetails["type"] == ".doc" || fileDetails["type"] == ".rtf" || fileDetails["type"] == ".pdf")) 
        { 
            // Get the URL of the files. 
            string url = getImageUrl(fileDetails); 
            DOM ele = args.Element; 
            string val = Convert.ToString((await ele.GetAttribute("data-uid"))); 
            ele.AddClass(new string[] { "e-file-preview-image" }); 
            // Call the client side function. 
            await JSRuntime.InvokeVoidAsync("setPreview", val, url); 
        } 
    } 
    public string getImageUrl(Dictionary<string, dynamic> data) 
    { 
        //Specify your controller action name 
        string baseUrl = "/api/Default/GetPreviewImage"; 
        string imgUrl = baseUrl + "?path=" + data["filterPath"] + data["name"]; 
        return imgUrl; 
    } 
} 
 
Refer the server side operations. 
 
  [Route("GetPreviewImage")] 
        public IActionResult GetPreviewImage(FileManagerDirectoryContent args) 
        { 
            string baseFolder = this.basePath + "\\wwwroot\\Files"; 
 
            try 
            { 
                String fullPath = baseFolder + args.Path; 
                string extension = Path.GetExtension(fullPath); 
                Stream imageStream = null; 
                if (extension == ".pdf") 
                { 
                    FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read); 
                    PdfRenderer pdfExportImage = new PdfRenderer(); 
                    //Loads the PDF document  
                    pdfExportImage.Load(fileStream); 
                    //Exports the PDF document pages into images 
                    Bitmap[] bitmapimage = pdfExportImage.ExportAsImage(0, 0); 
                    imageStream = new MemoryStream(); 
                    bitmapimage[0].Save(imageStream, System.Drawing.Imaging.ImageFormat.Png); 
                    imageStream.Position = 0; 
                    pdfExportImage.Dispose(); 
                    fileStream.Close(); 
                } 
                else if (extension == ".docx" || extension == ".rtf" || extension == ".doc") 
                { 
                    FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read); 
                    //Loads file stream into Word document 
                    WordDocument document = new WordDocument(fileStream, Syncfusion.DocIO.FormatType.Automatic); 
                    fileStream.Dispose(); 
                    //Instantiation of DocIORenderer for Word to PDF conversion 
                    DocIORenderer render = new DocIORenderer(); 
                    //Converts Word document into PDF document 
                    PdfDocument pdfDocument = render.ConvertToPDF(document); 
                    //Releases all resources used by the Word document and DocIO Renderer objects 
                    render.Dispose(); 
                    document.Dispose(); 
                    //Saves the PDF file 
                    MemoryStream outputStream = new MemoryStream(); 
                    pdfDocument.Save(outputStream); 
                    outputStream.Position = 0; 
                    //Closes the instance of PDF document object 
                    pdfDocument.Close(); 
 
                    PdfRenderer pdfExportImage = new PdfRenderer(); 
                    //Loads the PDF document  
                    pdfExportImage.Load(outputStream); 
                    //Exports the PDF document pages into images 
                    Bitmap[] bitmapimage = pdfExportImage.ExportAsImage(0, 0); 
                    imageStream = new MemoryStream(); 
                    bitmapimage[0].Save(imageStream, System.Drawing.Imaging.ImageFormat.Png); 
                    imageStream.Position = 0; 
 
                    fileStream.Close(); 
                } 
                else if (extension == ".ppt" || extension == ".pptx") 
                { 
                    IPresentation presentation = Presentation.Open(fullPath); 
                    //Initialize PresentationRenderer for image conversion 
                    presentation.PresentationRenderer = new PresentationRenderer(); 
                    //Convert the first slide to image 
                    imageStream = presentation.Slides[0].ConvertToImage(ExportImageFormat.Png); 
                    presentation.Dispose(); 
                } 
                FileStreamResult fileStreamResult = new FileStreamResult(imageStream, "APPLICATION/octet-stream"); 
               //Retur the image result. 
                return fileStreamResult; 
            } 
            catch (Exception e) 
            { 
                return null; 
            } 
 
        } 
 
Refer the sample line below. 
 
Refer the similar forum link for your reference. 
 
If you are facing any issue when implementing the similar in SQL file provider. We will happy to assist you. 
 
Please let us know, if you have any concerns. 
 
Regards,  
Sowmiya.P 


 



JB Joey Bailey January 20, 2021 12:32 PM UTC

This is no longer working, if i add a column using the old beta version referenced in the example project the column displays, if i use the newer current release.(18.4.0.35) the column is not displayed, and the other columns now display incorrectly.


SP Sowmiya Padmanaban Syncfusion Team January 21, 2021 10:35 AM UTC

Hi Joseph Bailey,  
 
Sorry for the inconvenience. 
 
We have checked your reported problem with FileManager component. We would like to inform you that we have marked the FileManager component as preview to final in Volume 4 Release. So, we have standardized the component behavior. In this standardization, we have included some breaking changes in the FileManager component.  
 
Note: 
 
Please note that we have introduced some API breaking changes in this release(v18.4.30). We would like you to review the breaking changes from the following location before you upgrade. Also, we have updated our documentation to the latest version(v18.4.35). 
 
 
After adding the additional parameter in read response, you need to add that additional attribute in FileManagerDirectoryContent class and refer the corresponding class as a TValue for FileManager component. 
 
Please, refer the below code snippet. 
 
<SfFileManager TValue="DirectoryContent" View="ViewType.Details"> 
    <FileManagerEvents TValue="DirectoryContent"></FileManagerEvents> 
   <FileManagerDetailsViewSettings> 
      <FileManagerColumns> 
        <FileManagerColumn Field="Name" HeaderText="FileName"></FileManagerColumn> 
        <FileManagerColumn Field="DateModified" HeaderText="Date Modified"> 
        </FileManagerColumn> 
        <FileManagerColumn Field="UrlValue"> 
          <HeaderTemplate> 
            <span>URL Name</span> 
          </HeaderTemplate> 
          <Template> 
            @{ 
              var data = (context as DirectoryContent); 
              <div>@data.UrlValue</div> 
            } 
          </Template> 
        </FileManagerColumn> 
      </FileManagerColumns> 
    </FileManagerDetailsViewSettings> 
    <FileManagerAjaxSettings Url="/api/Home/FileOperations" 
                             UploadUrl="/api/Home/Upload" 
                             DownloadUrl="/api/Home/Download" 
                             GetImageUrl="/api/Home/GetImage"> 
    </FileManagerAjaxSettings> 
  </SfFileManager> 
@code{ 
    public class DirectoryContent 
    { 
         ... 
         … 
      public string URL { get; set; } 
public string UrlValue { get; set; } 
    } 
} 
 
Controller 
 
switch (args.Action) 
      { 
        case "read": 
          // reads the file(s) or folder(s) from the given path. 
          return this.getFiles(args); 
} 
public object getFiles(FileManagerDirectoryContent args) 
    { 
      FileResponse readResponse = new FileResponse(); 
      try 
      { 
        var value = this.operation.GetFiles(args.Path, args.ShowHiddenItems); 
        DirectoryContent cwd = new DirectoryContent(); 
        readResponse.CWD = JsonConvert.DeserializeObject<DirectoryContent>(JsonConvert.SerializeObject(value.CWD)); 
        readResponse.CWD.URL = "https://github.com/SyncfusionExamples/ej2-aspcore-file-provider"; 
        readResponse.Files = JsonConvert.DeserializeObject<IEnumerable<DirectoryContent>>(JsonConvert.SerializeObject(value.Files)); 
        //Add the additional parameter for each files in filemanager component. 
        foreach (DirectoryContent file in readResponse.Files) 
        { 
          //Add the URL as additional parameter. 
          file.URL = "https://www.google.com/"; 
          // Add the URL value as addittiona parameter. 
          file.UrlValue = "Google"; 
        } 
        readResponse.Details = value.Details; 
        readResponse.Error = value.Error; 
        return readResponse; 
      } 
      catch 
      { 
        ErrorDetails er = new ErrorDetails(); 
 
      } 
      return this.operation.ToCamelCase(this.operation.GetFiles(args.Path, args.ShowHiddenItems)); 
    } 
 
Please, refer the sample link below. 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 


Loader.
Up arrow icon