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?