Download File using DirectEvent

  1. #1

    Download File using DirectEvent

    Hi! I'm trying to make a button for download a file, but I'm a little in trouble :(

    Which is the correct pattern with Razor developing model?

    In v5.3 WebForms setting the IsUpload property to the Click event was enough.
    isUpload doesn't exist anymore, so i've tried to use CustomConfig (look the commented row), but it doesn't work.

    .cshtml
    @page "{handler?}"
    @model ExtCookbook.Pages.FileDownloadModel
    @{
        ViewData["Title"] = "File Download";
    }
    
    <ext-section target="Main">
        <ext-panel id="MainContainer" region="Center" layout="Border" scrollable="true" paddingAsString="0">
            <items>
                <ext-button model="@Model.myButton" />
            </items>
        </ext-panel>
    </ext-section>
    .cshtml.cs
    using Ext.Net;
    using Ext.Net.Core;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    
    namespace ExtCookbook.Pages
    {
        public class FileDownloadModel : PageModel
        {
            public Button myButton { get; set; }
    
            public void OnGet()
            {
                var btn = new Button() { Id = "DownloadButton", IconCls = "x-md md-icon-get-app", Text = "Download" };
                btn.DirectEvents.Click.Method = HttpMethod.POST;
                btn.DirectEvents.Click.Url = $"?handler=DownloadButtonClick";
                //btn.DirectEvents.Click.CustomConfig = new JsObject() { { "isUpload", true } };
    
                myButton = btn;
            }
    
            public IActionResult OnPostDownloadButtonClick(JsObject jObj)
            {
                return File(System.Text.Encoding.UTF8.GetBytes("I have been downloaded via a DirectEvent!"), "text/plain", "test.txt");
            }
        }
    }
    Any suggestion is much appreciated!
    Thank you very much.
  2. #2
    Hello @bbros!

    Even in Ext.NET 5 and before, when you used the isUpload: true setting, you were effectively disabling the direct event functionality of the call. That is, a request can either return a direct event result (which includes script to handle changes in the page) -or- a file. Not both simultaneously. The following forum thread support this affirmation with an actual example: DirectEvent isUpload=true block other actions (fun fact: that's an exact 10,000 threads before this one -- ID-wise).

    In case the wanted behavior includes side effects from server (update a panel, etc), it would be necessary to make a callback after the actual direct event is done to effectively request the file. The direct event will work as usual, handling components or triggering messages display, and then the actual download can be wired up as a after, complete, or success callback to the direct event. For instance, the direct event could be used to generate the file and return an unique identifier to the generated file, along with a confirmation message, so that the success callback just requests that unique key (and possibly free up memory/disk with the fulfilled request).

    Here's an adaptation over your model code to display a simple message from the server event in the POST (actual direct event) handler, and return the file in the GET corresponding endpoint:

    public Button myButton { get; set; }
    
    public void OnGet()
    {
        var btn = new Button()
        {
            Id = "DownloadButton",
            IconCls = "x-md md-icon-get-app",
            Text = "Download"
        };
    
        btn.DirectEvents.Click.Method = HttpMethod.POST;
        btn.DirectEvents.Click.Success = "window.location = '?handler=DownloadButtonClick'";
        btn.DirectEvents.Click.Url = $"?handler=DownloadButtonClick";
    
        myButton = btn;
    }
    
    public IActionResult OnGetDownloadButtonClick()
    {
        return File(
            System.Text.Encoding.UTF8.GetBytes("I have been downloaded via a DirectEvent!"),
            "text/plain",
            "test.txt"
        );
    }
    
    public IActionResult OnPostDownloadButtonClick()
    {
        this.X().Toast("Download will start shortly...");
    
        return this.Direct();
    }
    The click.success handler could be anything to send the GET request (it does not necessarily need to be the same name, used it just to show how it tells apart get and post methods). For simplicity, I just set window.location but this may mess up browser history if you rely on that; it's up to your needs how you are going to make the request.

    What can probably be noticed is that it is not a direct request at all. It simply ïs an access to the endpoint that would download the file, as any a href would. In fact, the isUpload bit in v5 was just a shortcut (or maybe a convenience) to this behavior.

    If all needed is the download, then switch from direct event to a listener to query the file download endpoint and use it as you would the after/complete/success handlers.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. download file with DirectEvent on GridPanel
    By novacp in forum 2.x Help
    Replies: 1
    Last Post: Feb 13, 2014, 10:38 AM
  2. Download File using DirectEvent
    By Daniil in forum Examples and Extras
    Replies: 0
    Last Post: Dec 13, 2013, 4:02 AM
  3. [CLOSED] How to download a file in DirectEvent?
    By vadym.f in forum 1.x Legacy Premium Help
    Replies: 6
    Last Post: Jun 08, 2012, 1:20 PM
  4. [CLOSED] [1.0] DirectEvent File Download
    By Timothy in forum 1.x Legacy Premium Help
    Replies: 6
    Last Post: Jan 21, 2011, 6:04 PM
  5. [CLOSED] [1.0] - MVC - DirectEvent Download File
    By drkoh in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Jul 23, 2010, 8:26 PM

Posting Permissions