Я создал простой компонент Blazor для предварительного просмотра и загрузки изображений. Компонент InputFile скрыт, а метка используется в качестве кнопки для открытия диалогового окна выбора файла. После выбора файла/изображения я хочу показать изображение при предварительном просмотре. Я читаю файл и кодирую его в 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();
}
}
}
Когда я пробую компонент на другой странице Blazor, я наблюдаю странное поведение. Диалог загрузки (выбора файла) открывается дважды, изображение загружается только частично (см. прикрепленное изображение), и затем я не могу изменить (выбрать другое) изображение.
Итак, пожалуйста, подскажите мне, что происходит не так? Спасибо.
JS-функция:
function triggerClickEvent(elementId) {
document.getElementById(elementId).click();
}
Возможно, важно упомянуть: это приложение ASP.NET MVC, .NET 6. Я добавил services.AddServerSideBlazor(); в Startup.cs.
Используете ли вы этот компонент InputFile? Learn.microsoft.com/en-us/aspnet/core/blazor/…
Вы не предоставили метод для triggerClickEvent, но боюсь, что он используется для запуска диалогового окна загрузки файла. И это может быть проблемой, поскольку я тестировал <Inputfile />, который работал хорошо.
Да, я использую указанный вами компонент InputFile.





Я использовал код ниже, который работал хорошо.
@page "/Input"
@rendermode InteractiveServer
<h3>Inputfile Preview</h3>
<div class = "m-2">
<InputFile OnChange = "@HandleImageUpload" multiple accept = "image/*" />
@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 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();
}
}
}
Затем я использовал этот компонент в другом компоненте, он тоже работал хорошо.
Боюсь, Load (choose file) dialog opens twice,and then I cannot change это из-за кода JS, которым вы не поделились. Не могли бы вы поделиться кодом JS и тем, как вы использовали этот компонент в другом компоненте? И image is only partly loaded (see attached image) может быть связано с CSS
Зачем вам включать множественную загрузку, а затем брать только первый файл?
Скопировал фрагмент кода из официального документа и забыл удалить атрибут multipe. Моя вина, и я возьму только первый файл - коды из фрагмента кода ОП.
Я создал новое веб-приложение Blazor (серверная часть, .NET 8) и добавил код, но получил тот же результат:
@page "/input"
@rendermode InteractiveServer
<h3>Inputfile Preview</h3>
<div class = "m-2">
<InputFile OnChange = "@HandleImageUpload" multiple accept = "image/*" />
@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 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();
}
}
}
Пробовал Гугл Хром и Оперу. Одно изображение было загружено и показано правильно. Другие нет.
Когда я посмотрел на код элемента (изображения) в браузере, я увидел, что код base64 имеет «AAAAAAAAAAAAAAAAAAAA», начиная с 15% и до конца.
I tried Google Chrome and Opera. One image was loaded and shown correctly. Others not. --> Это значит, что один из браузеров работал хорошо? Или одно изображение хорошее, а два нет?
Это означает, что одно изображение хорошее, а два — нет.
Когда я посмотрел на код элемента (изображения) в браузере, я увидел, что код base64 имеет «AAAAAAAAAAAAAAAAAA» примерно до 15% и до конца.
В этой статье Загрузка файлов ASP.NET Core Blazor сказано, что SignalR имеет максимальный размер сообщения 32 КБ, и поэтому файлы обрезаются. Я пытался увеличить размер в Program.cs, но это не помогло.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddHubOptions( options => options.MaximumReceiveMessageSize = 1024 * 1024 * 10);
Привет, я нашел этот раздел, который может быть рекомендован Microsoft для загрузки изображений и предварительного просмотра. Learn.microsoft.com/en-us/aspnet/core/blazor/…
Этот пример работает для меня.
Чтобы избежать повторного открытия диалогового окна выбора файла, нам просто нужно добавить PreventDefault:
<label for = "productPictureInput" class = "btn btn-primary" style = "cursor: pointer;"
@onclick = "TriggerFileInput" @onclick:preventDefault = "true">Add Image</label>
Здравствуйте, во-первых, я предлагаю вам использовать эту библиотеку для входного файла от Microsoft fluentui-blazor.net/InputFile она неплохая, не нужно изобретать велосипед. Вторая запись файла в формате base64 и установка пути к нему могут привести к ошибкам. Что такое разрешение изображения? Существует предел того, насколько большим может быть изображение, передаваемое таким образом.