Blazor File Upload
I
wanted to see what it took to upload a file in a Blazor application. The use case I was using to validate the
process is adding an avatar to a user’s profile page. As I researched this I found that “there a
component for that “, I came across
Steve Sanderson’s <InputFile> component (See Steve’s Post)
Source Code
This post is my implementation of Steve’s InputFile
component. For a detail description of the
inner workings of the component see the link above. I will be using the Server Configuration for
my Blazor Application, but the component will work with any Blazor
configuration. Please note that the
implementation to save the uploaded file to the server is for only the Server
configuration. For the Client
configuration you would need a Server End point.
With the InputFIle component you can upload any file
type. For the displaying the uploaded
file we will be supporting only images and text files. There are of course components for PDFs and
office files. Available but that is beyond what are trying to achieve.
Usage
To use the component, you just add the component to your
page, then create a On Change event handler.
The event handler has an IFileListEntry[] object passed in. This parameter will contain from 0-n files
that were selected to be uploaded. This
allows the UI to control the user experience weather you are uploading a single
file, multiple files or even drag and drop.
Page:
<InputFile
OnChange="HandleSelection" />
Event Handler:
async Task HandleSelection(IFileListEntry[] files)
{
var file = files.FirstOrDefault();
if (file != null)
{
var ms = new MemoryStream();
await file.Data.CopyToAsync(ms);
}
status = $"Finished loading {file.Size} bytes from {file.Name}";
}
In the handler you can get each file and you can read it
into a memory stream. Once it is in the
stream you have full access to the .Net stream functionality to work with it.
Coding Note: You can only use async APIs on the stream
because the data has been transferred over the network.
Display Image
To display the uploaded file on the page as an image we need
to do the following:
1.
Ensure we are working with an image, we kept it
simple for this example
var
filetype = GetFileType(file.Name);
if (name.Contains("png") || name.Contains("jpg") || name.Contains("gif"))
2.
Read the file into a memory stream
var reader = new StreamReader(file.Data)
3.
Create a Base64String of the uploaded file data
to use as the source for the image tag.
string imageBase64Data = Convert.ToBase64String(ms.ToArray());
imageDataURL = string.Format("data:image/png;base64,{0}", imageBase64Data);
4.
Set the source of the <img> tag
<img src="@imageDataURL" style="height:300px;width:300px" />
Display Text File
To display a text file, we follow a similar path step
1.
Ensure we are working with a text file, again we
keep it simple
var fileType = GetFileType(file.Name);
if (fileType == "image")
2.
Read in the file to a memory stream
var reader = new StreamReader(file.Data)
3.
Read the contents of the file into a string
fileTextContents = await
reader.ReadToEndAsync();
4.
Display the string in the page
<pre>@fileTextContents</pre>
Saving the uploaded file to the server
This implementation is only for the Server configuration of
Blazor. To save the file to the server
it is as simple as saving a stream to a file.
var ms = new
MemoryStream();
await file.Data.CopyToAsync(ms);
using (FileStream newFile = new FileStream("wwwroot\\uploads\\" + file.Name, FileMode.Create, FileAccess.Write))
{
ms.WriteTo(newFile);
}
You should note the pathing on the FileStream. If you do not provide a path for the save it
will save the file to the root of you project.
If you want to have your application to access to the files once
uploaded, you need to place them in the wwwroot folder.
The InputFile component is available via NuGet or you could
just include the project with yours. You
will need to add the following configuration to you project for the component
to work.
1.
Add the NuGet package or the project to your
project
2.
In the _ImportFile add
@using BlazorInputFile
3.
In the _Host.cshtml add the script tag
<script src="_content/BlazorInputFile/inputfile.js"></script>
This turn out to be very easy and powerful. Blazor greatest feature is that it is
component based and that the community is awesome.
piggy backing https://blog.stevensanderson.com/2019/09/13/blazor-inputfile/
piggy backing https://blog.stevensanderson.com/2019/09/13/blazor-inputfile/
Source Code
Very helpful!
ReplyDelete