Чтение входного файла с помощью JSInterop из Blazor

Здравствуйте, я пытаюсь загрузить файл из локального хранилища с помощью FileReader api. Я протестировал js метод прямо на HTML странице, и он работает.

Однако при вызове с Blazor - JSRuntime я получаю следующую ошибку:

'Cannot read property 'files' of undefined
TypeError: Cannot read property 'files' of undefined

JS

window.methods = {
    fileChange:function(event) {
        var file = event.target.files[0];
        console.log("file retrieved");
        var reader = new FileReader();
        reader.onload = function (event) {
            console.log(reader.result);
        };
        reader.readAsText(file); 
    }
}

CSHTML

<input  type="file" onchange="@(async(x)=>await onFileChange(x))"/>
public async Task onFileChange(UIChangeEventArgs ev) {
            var str=await JSRuntime.Current.InvokeAsync<string>("methods.fileChange", ev.Value);
        }

P.S Итак, в соответствии с ошибкой метод вызывается успешно, но получает неопределенное значение. Нужно ли мне выполнять приведение или что-то еще, когда я использую InvokeAsync?

Мне нужно получить содержимое файла.


person Bercovici Adrian    schedule 04.02.2019    source источник


Ответы (2)


Для решения этой проблемы вы можете использовать прерывания JavaScript. Для решения этой проблемы уже доступны пакеты NuGet. Чтобы увидеть ответ в прямом эфире, см. Мое видео https://www.youtube.com/watch?v=-IuZQeZ10Uw&t=12s

В видео для взаимодействия JavaScript используется пакет NuGet под названием Blazor.FileReader. С помощью Blazor.FileRead я смог прочитать input создание URI данных и загрузку его в Azure Cognitive Services. Вы можете увидеть код ниже.

@using Blazor.FileReader
@using System.IO;
@using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
@using Newtonsoft.Json;

@page "/fetchdata"
@inject HttpClient Http
@inject IFileReaderService fileReaderService;

<h1>Cognitive Services Vision</h1>

<input type="file" id="fileUpload" ref="fileUpload" onchange="@UploadFile" />

<img src="@imageData" style="@( analysis != null ? $"border: 5px solid #{analysis.Color.AccentColor}" : "" )" />

@if (analysis == null)
{
    <p>Select an image</p>
}
else
{
    <p>@analysis.Description.Captions.First().Text</p>
    <p>@analysis.Color.AccentColor</p>
    <ul>
        @foreach (var tag in analysis.Tags)
        {
            <li>@tag.Name</li>
        }
    </ul>
}
@functions {

    ElementRef fileUpload;
    string imageData = String.Empty;
    ImageAnalysis analysis;

    async Task UploadFile()
    {
        var files = await fileReaderService.CreateReference(fileUpload).EnumerateFilesAsync();

        using (MemoryStream memoryStream = await files.First().CreateMemoryStreamAsync())
        {
            byte[] bytes = memoryStream.ToArray();

            imageData = $"data:image/jpg;base64,{Convert.ToBase64String(bytes)}";
            var response = await Http.PostAsync(
                    requestUri: "api/SampleData/Save",
                    content: new ByteArrayContent(bytes)
                );
            analysis = JsonConvert.DeserializeObject<ImageAnalysis>(await response.Content.ReadAsStringAsync());

        }
    }

}
person Ed Charbeneau    schedule 04.02.2019
comment
Спасибо за ваш ответ ! Хотя я искал более raw подход, чтобы увидеть, как DYI взаимодействовать. - person Bercovici Adrian; 04.02.2019
comment
Для грубого подхода просто используйте исходный код Blazor.FileReader github.com/Tewr/BlazorFileReader. - person Ed Charbeneau; 04.02.2019

Приятель, почему вы обрабатываете переданный параметр функции fileChange, как если бы это был объект события? Нет. Посмотрите еще раз на свой код, ev.Value не является объектом события. Это строковое значение имени файла. Попробуйте вместо этого:

window.methods = {
    fileChange:function(fileName) {

        console.log("file retrieved: " + fileName);

 }
}

Надеюсь это поможет...

person enet    schedule 04.02.2019
comment
Мне нужно получить содержимое файла, а не имя. - person Bercovici Adrian; 04.02.2019
comment
Я очень хорошо знаю, что вы хотите сделать, и уже сказал вам об этом. Прочтите также мой предыдущий ответ. Еще раз, значение UIChangeEventArgs.Value - это имя файла. Верно. Теперь вы должны передать этот файл функции fileChange. См. Мой текущий ответ выше. Эта функция имеет единственный строковый параметр, который, опять же, является именем файла, предоставленным вам UIChangeEventArgs.Value. Теперь используйте FileReader API, чтобы прочитать содержимое файла. Прочтите мой первый ответ выше. Попробуйте сделать это самостоятельно. Если у вас не получится, создайте новый вопрос с отображением вашего кода, и я решу проблему за вас. - person enet; 04.02.2019
comment
Что ж, это то, что я пытаюсь сделать, чтобы прочитать содержимое FileReader api. Ваш ответ действительно предоставляет filename, но, как вы можете видеть в моем сообщении, я пытался использовать FileReader api. - person Bercovici Adrian; 04.02.2019
comment
это не ответ, потому что он не предоставляет содержимое файла, а только имя файла. - person Rich Bryant; 04.02.2019
comment
@Rich Bryant, это ответ ... Я ему точно сказал, почему он получает ошибку. Он все еще там (в его вопросе), хотя позже он обновил свой исходный вопрос. См. Мой комментарий выше. Его вопрос был не в том, как читать содержимое файла. И снова дело в ошибке. - person enet; 04.02.2019