Download documents from the Filesystem webserver

Hi ,
I have a huge amount of files ( Word, Excel , MSG ) on the webserver, these files are not in the database.
How can I create a download link from within Radzen (Angular).

I wanted to ask before using any additional third party or custom modules .

Case:
Documents stored on filesystem on server : \servername\share\folder\file.docx
In database I have a table with the name of the file and server location to the folder and file .

I want to make this file downloadable for the users of the application.

Searched the forum but can not find , probably using the wrong keywords.
Thank you for your help.

Hi @mcanavar,

Radzen does not support this out of the box. You can however use a custom server method for that (or create another controller). Here is a sample implementation of such a method (inspired by this SO question):

[Route("api/[controller]/[action]")]
public class ServerMethodsController
{
  // Inject a EF context to your database 
  // Check https://www.radzen.com/documentation/invoke-custom-method/#create-the-custom-method-that-executes-the-db-query
   MyDataSourceContext context;

   public ServerMethodsController(MyDataSourceContext context)
   {
       this.context = context;
   }

   [HttpGet("download")]
   public IActionResult GetBlobDownload([FromQuery] string fileName)
   {
       // Find the local file name from the DB
       var file = context.Files.Where(file => file.FileName == fileName).FirstOrDefault();
       
       if (file == null || !File.Exists(file.FileName))
       {
           return NotFound();
       }
       
       // Get a stream to the file
       using var content = System.IO.File.OpenRead(file.FileName);

       // Return the file
       return File(content, "application/octet-stream", fileName);
   }
}

Then to use it in your Angular pages create links to '/api/servermethods/download?fileName=<required filename>' for example '/api/servermethods/download?fileName=test.xlsx'

Hi Atanas,

I'm getting a: ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'api/ServerMethods/download'

any Idea?

That's probably the Angular router getting in the way. You can try using the full URL.

with full url you mean: http://localhost:8000/api/serverMethods/download?filename=12

if I construct this and paste it in the browser , have the same result and error in the debuger.

I'll investigate more.

This would mean that the ASP.NET Core Router does not match at all the server controller. Also the port of the server is usually 5000 not 8000

When debugging with VS it does not hit the method breakpoint.
Get call has a 200 :
https://www.xxxxx.nl/radzenapp/api/ServerMethodsController/download?documentID=12688
image

in console :

Why are these "simple" task so troublesum I ask myself :frowning:

You can try hardcoding the Route of the ServerMethodsController:

[Router("/api/server")]

Then use /api/server/download?fileName=example.pdf

Because you are using the wrong URL ...

https://www.xxxxx.nl/radzenapp/api/ServerMethodsController/download?documentID=12688

should have been

https://www.xxxxx.nl/radzenapp/api/ServerMethods/download?documentID=12688

If you continue to get Angular router errors then ASP.NET still cannot match the URL of the action because it is wrong. As a result it returns the index.html page in order to properly support the Angular router.

I have changed the route to "ServerMethodsController" to check if it would return a 200 .
in the .CS I have allready a route decoration.

Snippet

[Route("api/[controller]/[action]")]

I am afraid I don't understand what the problem is. This is quite a simple thing and is basically the way Radzen implements custom server methods. I still think you are not using the right URL since it never hits the action even when requested from the browser address bar. If you need further assistance you can send a runnable version of your project to info@radzen.com

you are probably right : I will package this solution and send it to you.
It is the deadline and work at home stress I think.

Thank you for listening and your support.

the reset password , default route /auth/ does also not work , so there is something else going on and not just with the download.
I wil check with my other applications if this is not due to an update or change .

Hi Krochev,
Is it possible for you to create an working example of this sample? I have tried all sorts of routing changes and this action does not hit.
hit the wall here..

Hey @mcanavar,

Not sure what exactly you've tried at your end however here is a simple as possible code:

invoking it from a button works.
I was using your suggestion to do it from a link.
I have a datagrid and have used a template for one column
Added a link component and given the path : /api/ServerMethods/filedownload/${data.document_id}
image

In the datagrid it creates a nice link to click on:
image

but does not route .

The custom method returns a File to the button click result, wil this invoke an file download in the browser ?

Relatives url will not work in the development since the file will be served from the .NET application running on port 5000 while the Angular application is served on port 8000 and the Angular rooter will try to open the url first. Here is an example with real file downloaded from a link where fileName is a page property initialized on page load:



so we have to hardcode the url , what is the URL for the production when deployed ?
You are using Http , on deploy it will stay http or https ?

You can create the URL at runtime using the properties of the location - hostname, port, etc..