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) 


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/


Source Code
























Comments

Post a Comment

Popular posts from this blog

Yes, Blazor Server can scale!

Blazor new and improved Search Box

Blazor Wizard Step Component