web-dev-qa-db-ja.com

Blazorでファイルをアップロードする最善の方法は何ですか?

私は BlazorInputFile ライブラリであるが、2019年10月からオープンされたPRSがあり、このライブラリが今維持されていることはわかりません。また、BlazorにJSを使用してファイルをアップロードできる方法についてのブログのカップル記事を見つけました。私はBlazorでファイルをアップロードするための最良の方法が何であるかを理解しようとし、可能な場合はJSを使用したくありません。多分誰かがすでにこの問題を調査し、最善の解決策を見つけましたか?

5
Sergey Pitenko

コンポーネントといくつかのJavaScriptを使用してこれを行います(ボタンのように見えます)。コンポーネントとJSが組み込まれたら、再び心配する必要はありません...

これがアップロードコンポーネント(upload.razor)です。

@inject IJSRuntime JSRuntime

@if (AllowMulitple)
{
    <input id="Xinputfile00" type="file" accept="@Filter" @onchange="UploadFile" multiple hidden />
}
else
{
    <input id="Xinputfile00" type="file" accept="@Filter" @onchange="UploadFile" hidden />
}
<button class="btn btn-default" @onclick="ClickUpload">@Title</button>

@code {

    [Parameter]
    public FileData[] Files { get; set; }

    [Parameter]
    public string Filter { get; set; }

    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public bool AllowMulitple { get; set; }

    [Parameter]
    public Action Uploaded { get; set; }

    async Task UploadFile()
    {
        string[] result = await JSRuntime.InvokeAsync<string[]>("blazorExtensions.GetFileData", "Xinputfile00");
        List<FileData> results = new List<FileData>();
        foreach (string file in result)
        {
            results.Add(new FileData(file));
        }
        this.Files = results.ToArray();
        if (Uploaded != null)
        {
            Uploaded();
        }
    }

    async Task ClickUpload()
    {
        await JSRuntime.InvokeVoidAsync("blazorExtensions.InvokeClick", "Xinputfile00");
    }

    public class FileData
    {
        public string Base64 { get; set; }
        public string MIMEType { get; set; }

        public byte[] Bytes
        {
            get
            {
                return Convert.FromBase64String(this.Base64);
            }
        }

        public FileData(string data)
        {
            if (string.IsNullOrWhiteSpace(data) || !data.Contains(","))
            {
                return;
            }
            string[] alldata = data.Split(',');
            this.MIMEType = alldata[0].Remove(0, 5).Replace(";base64", "");
            this.Base64 = alldata[1];
        }

    } _

これがJavaScriptの抜粋です:

window.blazorExtensions = {

    GetFileData: async function (id) {
        var target = document.getElementById(id);
        var filesArray = Array.prototype.slice.call(target.files);
        return Promise.all(filesArray.map(window.blazorExtensions.fileToDataURL));
    },

    fileToDataURL: async function (file) {
        var reader = new FileReader();
        return new Promise(function (resolve, reject) {
            reader.onerror = function () {
                reader.abort();
                reject(new DOMException('Error occurred reading file ' + file));
            };
            reader.onload = function (event) {
                resolve(reader.result);
                console.log('resolved');
            };
            reader.readAsDataURL(file);
            console.log('returned');
        })
    },  

    InvokeClick: function (id) {
        var elem = document.getElementById(id);
        if (typeof elem.onclick == "function") {
            elem.onclick.apply(elem);
        }
        elem.click();
    },
} _

そしてこれが呼び出しマークアップのサンプルです:

<Upload @ref="upload" Filter=".xlsx" Title="Upload" AllowMulitple="false" Uploaded="DoMyExcelThingOrSomething" /> _

そしてそれがアップロード後に呼び出されるメソッド

    void DoMyExcelThingOrSomething()
{
    if (upload.Files.Length < 1 || string.IsNullOrWhiteSpace(upload.Files[0].Base64))
    {
        //...nothing good here...
        return;
    }
    //play with upload.Files here...
}
 _
0
Will