how display directories and files to open the files in server side in datatable?

sblb 1,231 Reputation points
2022-06-30T08:47:28.997+00:00

Hi,
I've an application aspNet core 5 razor page to display several datatable associated to the view in sql.
the view is :
216357-image.png

The data is located in File Table where is the files and directories.

Right now my application returns all files of the directories and subdirectories.
216501-image.png

To display the files I used relative path. How I can modify the method of the relative path to display the directories and subdirectories to have acces to the files? also in my datatable I would like to add a column to identify the directories with logo directories et files with logo.

Actually I used the webapi action

 [HttpGet]  
        public async Task<IActionResult> GetFileByFilePath(string relativePath)  
        {  
             string directory = await _filerepository.GetFileTableDirectory();  
            string path = $"{directory}\\{relativePath}";  
  
           if (System.IO.File.Exists(path))  
          {  
               return File(System.IO.File.OpenRead(path), "application/octet-stream", Path.GetFileName(path));  
          }  
             return NotFound();  
        }  

Service method

 public async Task<string> GetFileTableDirectory()  
        {  
            FileTableRoot results = await _context.Set<FileTableRoot>()  
                .FromSqlRaw("SELECT FileTableRootPath() as Name").FirstOrDefaultAsync();  
            return $"{results?.Name}";  
        }  

I tried to modified webapi action and associate services

 [HttpGet("{filename}")]  
 public async Task<IActionResult> GetAsync(string filename)  
 {  
     string directory = await _fileTableService.GetFileTableDirectory();  
     string path = $"{directory}\\{filename}";  
      
     if(System.IO.File.Exists(path))  
     {  
         return File(System.IO.File.OpenRead(path), "application/octet-stream");  
     }  
     return NotFound();  
 }  

This action seems not adapted to my application.

Have you any suggestions?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,806 questions
0 comments No comments
{count} votes

Accepted answer
  1. AgaveJoe 29,946 Reputation points
    2022-07-02T10:45:24.54+00:00

    Is it necessary to go through the search value?

    Of course not. The Search input the easiest approach because the Search input is designed to filter records. Plus the server side processing is setup.

    You selected the jQuery DataTable as the presentation design. In my opinion, the jQuery DataTable is a poor HTML design for displaying a directory structure. An unordered list is a much better representation and the approach I recommended around 5 months ago.

    With that being said, it is up to you to come up with a design

    As you suggested, the key to the code is to have created the two columns in the view; I think we can do something with that.

    I have no idea what you are thinking... IsDirectory is currently being used in the jQuery DataTable to render HTML for a file or a directory.

    The SQL View returns the relative path. It seems to me the relative path is the key. Write a service method that returns a distinct list of relative paths. Use this list in your HTML design. For example, a standard HTML select (dropdown). The user selects an option from the select which sets a column filter.

    The jQuery DataTable has the ability to add column filters. Place the select in the path column header. See the openly published jQuery DataTable documentation.

    https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html

    2 people found this answer helpful.

13 additional answers

Sort by: Most helpful
  1. sblb 1,231 Reputation points
    2022-07-01T18:11:20.977+00:00

    First of all I would like to say a big thank you because I have made a lot of progress with your code evolution proposal.

    Remove the last directory from the path in the Search input.

    if I put myself as a user this way does not seem practical to me.
    Is it necessary to go through the search value? As you suggested, the key to the code is to have created the two columns in the view; I think we can do something with that.

    I believe your initial questions has been answered.

    You're right, but i don't have the hand to accept it there is no accept answer icon

    0 comments No comments

  2. sblb 1,231 Reputation points
    2022-07-01T14:47:27.533+00:00

    I'm not sure what changes you've made to the source.

    The change I have so far is the modification of the sql view excepted in service api :

    .FromSqlRaw($@"SELECT ds.[stream_id] AS Id
    ,ds.[file_stream].GetFileNamespacePath() As [Path]
    ,ds.[name] As [Name]
    ,ds.[file_type] As [Type]
    ,ISNULL(ds.[cached_file_size],0) AS [Size]
    ,CAST(ds.[creation_time] as [Created])
    ,ds.is_archive as [IsArchive]
    ,ds.is_directory as [IsDirectory]
    FROM [dbo].[wPreliminaire] AS ds").ToListAsync();

    So, I've made exactly that you've done in your previous post.

    Modification in service api : right!
    Modification in sql view : right !
    Add the function and the code modification in jquery : right !

    Jquery + function

       function setSerach(value) {  
            $("#customerDatatable").dataTable().fnFilter(decodeURI(value));  
        }  
    
        $(document).ready(function () {  
    
            $('#customerDatatable.table').dataTable({  
               //...  
                "columns": [  
                    { "data": "path", "name": "path", "autoWidth": true },  
                    {  
                        "data": "path", "name": "path", 'render': function (data, type, row, meta) {  
                            if (row.isDirectory) {  
                                return '<a href="javascript:void" onclick="setSerach(\'' + encodeURI(row.path) + '\'); return false;">' + row.path + '</a>';  
                            } else {  
                                return '<a href="/api/wPreliminaire/?relativePath=' + row.path + '" >' + row.name + '</a>';  
                            }  
                        }  
                   },             
                   { "data": "type", "name": "type", "autoWidth": true },  
                   {  
                        "data": "size", "name": "size", "autoWidth": true, 'render': function (data, type, row, meta) {  
                            var size = BigInt(data);  
                            if (size < 1024) { return size + ' B' }  
                            return size / BigInt(1024) + ' KB';  
                        }   
                    },       
                    { "data": "created", "name": "created", "autoWidth": true}              
                ]  
            });   
    
        });  
    

    You'll use the is_directory field in the the jQuery DataTable column definitions to determine the difference between a file and directory then render whatever HTML fits your design.

    This corresponds to the change you made in jquery with the condition if(row.isDirectory)

    when I run the application there is no change.

    I would like to propose a small modification in jquery at the condition level: if(row.isDirectory==1)


  3. sblb 1,231 Reputation points
    2022-07-01T15:15:05.517+00:00

    Now I can acces to the repository.

    There are two things :
    1 - I can't go back to the previous directories
    2 - as you can see in the image below the path of the directory is put in the "search" area when I click on a directory; how could I not have the path in the search area

    216978-image.png


  4. sblb 1,231 Reputation points
    2022-07-01T16:07:59.927+00:00

    I can't read your mind and have no idea what "go back to the previous directories" means in the context of your application.

    I want to say make an URL to going up one level.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.