Bradley Wells
Posted on November 18, 2019
After completing this tutorial, you will know how to download and save a file locally to your computer using JavaScript interop in a Blazor application.
The techniques in this lesson could be used to build upon the functionality of the previous tutorial, where you learned how to write to LocalStorage in a Blazor WebAssembly app. In that tutorial, you created a basic text editor where the contents of a note could be saved across browser sessions.
The JavaScript Component
For now, there is no built-in functionality for saving a file in Blazor. It is necessary to write the function in JavaScript, as you would with more traditional web applications, and then invoke the JavaScript function from within your Blazor application’s C# code.
To begin, create a file called SaveFile.js in your project’s wwwroot folder. This file will contain a JavaScript function that you will call from your C# code.
function FileSaveAs(filename, fileContent) {
var link = document.createElement('a');
link.download = filename;
link.href = "data:text/plain;charset=utf-8," + encodeURIComponent(fileContent)
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
The function, named FileSaveAs
, takes two arguments, a filename and the content that will form the body of the plaintext document. To save other filetypes, make the appropriate adjustments. Load the script in wwwroot/index.html just before the closing body tag </body>
.
<script src="SaveFile.js"></script>
Execute JS Using JSInterop
To use a JSInterop in Blazor, you must inject an instance of the IJSRuntime
object into the Razor component from which you wish to execute the JavaScript code. For the purpose of this tutorial, you can use the Index.razor page.
@page "/"
@inject IJSRuntime JSRuntime
You will refer to this instance of IJSRuntime
by the name JSRuntime
. However, before actually using the object, go ahead and lay out the UI of the page.
<h1>Blazor Download File</h1>
<textarea @bind="noteContent" />
<br />
<button @onclick="DownloadFile">Download</button>
This example consists of a simple textarea
field, with value bound to a string, noteContent
, and a button whose click event will be handled by a method called DownloadFile
.
Next, create the noteContent
string variable. Also, define a variable named fileName
and initialize it with a default filename, such as note.txt. This name will be used when downloading the file.
@code {
string noteContent;
string fileName = "note.txt";
}
Now you are ready to use the JavaScript interop by invoking the instance of the JS runtime you injected previously. You must invoke the JSInterop asynchronously, so do not forget to create the DownloadFile
method as an async
method.
public async void DownloadFile()
{
await JSRuntime.InvokeAsync<object>(
"FileSaveAs",
fileName,
noteContent
);
}
This method calls the FileSaveAs
function from SaveFile.js. Remember, you loaded this script file in wwwroot/index.html. The values fileName
and fileContent
correspond to the two arguments expected by the FileSaveAs
function. Since this example’s textarea
field is bound to noteContent
, the current value of textarea
will already be stored in noteContent
. When the Download button is clicked, your Blazor application will save the contents of the note as notes.txt.
A Complete Example
You are finished! In this tutorial, you learned how to save a file locally from a Blazor application. You wrote a JavaScript function to open the File > Save As… dialog, and then you used Blazor’s JSInterop capability to execute that function from a C# event handler, passing C# variables to the JavaScript function.
Your completed Index.razor may look like the following.
@page "/"
@inject IJSRuntime JSRuntime
<h1>Blazor Download File</h1>
<textarea @bind="noteContent" />
<br />
<button @onclick="DownloadFile">Download</button>
@code {
string noteContent;
string fileName = "note.txt";
public async void DownloadFile()
{
await JSRuntime.InvokeAsync<object>(
"FileSaveAs",
fileName,
noteContent
);
}
}
You could use this technique to add functionality to the notepad-like text editor you began developing in the previous tutorial. This time, you could trigger a file download by clicking a button, thus allowing you to save the contents of a given note to your hard drive. If you have any questions, do not hesitate to ask in the comments.
Posted on November 18, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.