I created simple Blazor component for pictures preview and upload. InputFile component is hidden and label is used as button to open choose file dialog. After file/image choosing I want to show the image on preview. I read the file end encode it to base64.
@using Microsoft.AspNetCore.Components.Forms
@inject IJSRuntime JSRuntime
<div class="m-2">
<InputFile style="display: none" id="productPictureInput" OnChange="HandleImageUpload" accept="image/*" />
<label for="productPictureInput" class="btn btn-primary" style="cursor: pointer;" @onclick="TriggerFileInput">Add Image</label>
@if (imagePreviewSrc != null)
{
<img src="@imagePreviewSrc" alt="Image preview" style="max-width: 200px; max-height: 200px; margin-left: 10px;" />
}
</div>
@code {
private string? imagePreviewSrc;
private async void TriggerFileInput()
{
await JSRuntime.InvokeVoidAsync( "triggerClickEvent", "productPictureInput" );
}
private async void HandleImageUpload(InputFileChangeEventArgs e)
{
var imageFile = e.GetMultipleFiles().FirstOrDefault();
if (imageFile != null)
{
var imageStream = imageFile.OpenReadStream();
var buffer = new byte[imageStream.Length];
await imageStream.ReadAsync(buffer);
imagePreviewSrc = $"data:image/jpg;base64,{Convert.ToBase64String(buffer)}";
StateHasChanged();
}
}
}
When I try the component on other Blazor page I get strange behavior.
Load (choose file) dialog opens twice, image is only partly loaded (see attached image) and then I cannot change (choose other) image.
So please tip me what's is going wrong? Thanks.
JS function:
function triggerClickEvent(elementId) {
document.getElementById(elementId).click();
}
It might be important to mention - it's ASP.NET MVC application, .NET 6. I added services.AddServerSideBlazor();
to Startup.cs.
To avoid opening choose file dialog twice we just need to add preventDefault:
<label for="productPictureInput" class="btn btn-primary" style="cursor: pointer;"
@onclick="TriggerFileInput" @onclick:preventDefault="true">Add Image</label>