【问题标题】:Reading input file with JSInterop from Blazor从 Blazor 使用 JSInterop 读取输入文件
【发布时间】:2019-06-28 02:49:18
【问题描述】:

您好,我正在尝试使用 FileReader api 从本地存储加载文件。 我已经直接在HTML 页面中测试了js 方法,它可以工作。

但是,当从 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);
        }

附言 所以根据错误,该方法被成功调用,但它收到一个未定义的。当我使用InvokeAsync时,我需要做一个强制转换吗?

我需要获取文件的内容。

【问题讨论】:

    标签: javascript interop blazor


    【解决方案1】:

    您可以使用 JavaScript 互操作来解决这个问题。已经有 NuGet 包可用于处理此问题。答案的现场视频演示请看我的视频https://www.youtube.com/watch?v=-IuZQeZ10Uw&t=12s

    在视频中,名为 Blazor.FileReader 的 NuGet 包用于 JavaScript 互操作。使用 Blazor.FileRead,我能够读取 input 创建数据 URI 并将其上传到 Azure 认知服务。你可以看下面的代码。

    @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());
    
            }
        }
    
    }
    

    【讨论】:

    • 感谢您的回答!虽然我正在寻找更多 raw 的方法,但看看如何 DYI 互操作部分。
    • 对于“原始”方法,只需使用 Blazor.FileReader 的源代码github.com/Tewr/BlazorFileReader
    【解决方案2】:

    哥们,你为什么把传递给fileChange函数的参数当成一个事件对象呢?它不是。再看看你的代码,ev.Value 不是事件对象。它是文件名的字符串值。试试这个:

    window.methods = {
        fileChange:function(fileName) {
    
            console.log("file retrieved: " + fileName);
    
     }
    }
    

    希望这会有所帮助...

    【讨论】:

    • 我需要获取文件的内容而不是名称。
    • 我很清楚你想做什么,并且已经告诉你了。也阅读我之前的答案。再次, UIChangeEventArgs.Value 的值是文件名。正确的。现在,您应该将此文件传递给 fileChange 函数。请参阅上面我当前的答案。此函数有一个字符串参数,它再次是 UIChangeEventArgs.Value 提供给您的文件名。现在使用 FileReader API 来读取文件的内容。阅读我上面的第一个答案。试着自己做。如果您不成功,请创建一个新问题,显示您的代码,我会为您解决问题。
    • 这就是我想要做的,阅读FileReader api 的内容。您的回答确实提供了filename,但正如您在我的帖子中看到的那样,我尝试使用FileReader api。
    • 这不是答案,因为它不提供文件的内容,只提供文件名。
    • @Rich Bryant,这就是答案......我已经告诉他他为什么会出错。它仍然存在(在他的问题中),尽管他后来更新了他原来的问题。见我上面的评论。他的问题不是关于如何读取文件的内容。这又是关于错误。
    猜你喜欢
    • 2015-06-11
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 2020-05-23
    相关资源
    最近更新 更多