Dropzone.js in Blazor Application

54 Views Asked by At

I am writing a Blazor application and want to try my hand at JSInterop and the Dropzone.js library. However, I can't get over the hurdle of transferring the actual attachment data between the javascript and Blazor component for the following scenarios:

  • When a Thumbnail is created
  • When a full image is processed

"Working" Example (Thumbnail)

@using Microsoft.Extensions.Logging

@inject IJSRuntime JSRuntime

@rendermode InteractiveServer

<div class="col-12">
    <div class="card">
        <div class="card-body">
            <h4 class="header-title">Image Uploads</h4>
            
            <div class="row">
                <div class="col">
                    <form action="/" method="post" class="dropzone dz-clickable" id="image-uploads">
                        <div class="dz-message needsclick">
                            <i class="h1 text-muted mdi mdi-upload"></i>
                            <h4>Drop files here or click to upload.</h4>                            
                        </div>
                    </form>
                </div>

                <div class="col">
                    <div class="dropzone-previews mt-3" id="file-previews"></div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- file preview template -->
<div class="d-none" id="uploadPreviewTemplate">
    <div class="card mt-1 mb-0 shadow-none border">
        <div class="p-2">
            <div class="row align-items-center">
                <div class="col-auto">
                    <img data-dz-thumbnail="" src="#" class="avatar-sm rounded bg-light" alt="">
                </div>
                <div class="col ps-0">
                    <a href="javascript:void(0);" class="text-muted fw-bold" data-dz-name=""></a>
                    <p class="mb-0" data-dz-size=""></p>
                </div>
                <div class="col-auto">
                    <!-- Button -->
                    <a href="" class="btn btn-link btn-lg text-muted" data-dz-remove="">
                        <i class="fe-x"></i>
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>

@code {
    [Parameter, EditorRequired]
    public ImageAttachmentsModel Model { get; set; } = null!;

    [Parameter]
    public EventCallback<ImageAttachmentsModel> ModelChanged { get; set; }

    private DotNetObjectReference<ImageUploads>? objRef;

    [JSInvokable]
    public void OnThumbnailCreated(string name, long sizeBytes, string contentType)
    {
        // Handle the thumbnail creation event
        Console.WriteLine($"Thumbnail created.");
    }

    protected override async Task OnInitializedAsync()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("dropZoneInterop.initializeDropZone", objRef);
        }
    }
}
window.dropZoneInterop = {
    initializeDropZone: function (dotNetHelper) {
        // Initialization logic for Dropzone
        var myDropzone = new Dropzone("#image-uploads",
            {
                paramName: "file",
                maxFilesize: 5,
                acceptedFiles: ".jpg, .jpeg, .png, .gif",
                addRemoveLinks: true,
                previewsContainer: "#file-previews",
                previewTemplate: document.querySelector('#uploadPreviewTemplate').innerHTML,
                init: function () {
                    this.on("thumbnail",
                        function (file, dataUrl) {
                            dotNetHelper.invokeMethodAsync('OnThumbnailCreated', file.name, file.size, file.type);
                        });
                }
            });
    }
};

The Problem

In the javascript, Dropzone has an event that contains dataUrl that the example above doesn't use:

'data:image/png;base64,iVBORw0KGgoAAAANSU...'

It is a base64-encoded string. If I try and pass that into the Blazor component as a string it throws an error in the browser. But it's very generic (Connection Lost).

My Question

Is there a better way to approach passing file data between dropzone and my Blazor component?

0

There are 0 best solutions below