Blazor Download/Save a File using JSInterop
Tags: csharp, dotnet, webdev, tutorial
Published: 2019-11-18 11:23:34

---
title: Blazor Download/Save a File using JSInterop
published: true
tags: csharp, dotnet, webdev, tutorial
canonical_url: https://wellsb.com/csharp/aspnet/blazor-jsinterop-save-file/
---

[Original Article](https://wellsb.com/csharp/aspnet/blazor-jsinterop-save-file/)

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](https://wellsb.com/csharp/aspnet/blazor-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.

```js
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>`.

```html
<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.

```csharp
@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.

```html
<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.

```csharp
@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.

```csharp
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.

[![](https://wellsb.com/csharp/wp-content/uploads/sites/2/2019/11/blazor-download-file-min.gif)](https://wellsb.com/csharp/wp-content/uploads/sites/2/2019/11/blazor-download-file-min.gif)

Your completed **Index.razor** may look like the following.

```csharp
@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](https://wellsb.com/csharp/aspnet/blazor-write-to-localstorage/). 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.

[Source](https://wellsb.com/csharp/aspnet/blazor-jsinterop-save-file/)