BlazorFileReader
Library for creating read-only file streams from file input elements or drop targets in Blazor.
Install / Use
/learn @Tewr/BlazorFileReaderREADME
BlazorFileReader
Blazor library exposing read-only file streams in Blazor
using <input type="file" />
and FileReader. Drag and drop targets may also be used to initialize streams.
Here is a Live demo that contains the output of the wasm demo project. Currently, its a build based on v3.2.0.
Installation
Use Nuget: Install-Package Tewr.Blazor.FileReader
Make sure your environment is up to date with the appropriate SDK and VS2019 16.6. See this article for more details. Depending on your project type, use one of the two examples below. For a complete use-case, see the client or server-side demo projects.
Client-side / Wasm Project type / "CSB"
Setup IoC for IFileReaderServiceas in (Program.cs):
services.AddFileReaderService(options => options.UseWasmSharedBuffer = true);
Server-side / asp.net core Project type / "SSB"
Setup IoC for IFileReaderService as in the example (Startup.cs):
services.AddFileReaderService();
Documentation
The public API is documented here, generated from the XML comments.
To get started, the best is to look at the example razor files in the demo project.
<details><summary>Serverside/SSB: Important usage notice for versions prior to 2.1</summary>Optional SignalR Configuration for large buffer sizes
The following notice is important for versions prior to 2.1. As of 2.1, it is no longer neccessary to modify MaximumReceiveMessageSize. While doing so may slightly increase transfer speed, "we recommend < 32K per message since they are being stored in a ring buffer (default size 5000). Storing larger messages will be awful for performance" (<a href="https://github.com/SignalR/SignalR/issues/1205">@DavidFowl, msft, 2012</a>).
For server-side hosting, bufferSize + metadata (up to ~30%, depending on buffersize) should not exceed the SignalR MaximumReceiveMessageSize setting, or you will encounter a client-side exception if the file is larger than bufferSize.
Make sure MaximumReceiveMessageSize exceeds your bufferSize with 30% to be on the safe side. It is also recommended to set a fixed upper file size in the input tag or validate file.Size in code before starting the uploading. The default settings is 32KB. Thus, if you leave this setting untouched, you should not use a buffer size exceeding 22KB.
You can set the MaximumReceiveMessageSize like this in Startup.cs (creds @ADefWebserver for mentioning this). Microsoft Docs
services.AddServerSideBlazor().AddHubOptions(o =>
{
o.MaximumReceiveMessageSize = 10 * 1024 * 1024; // 10MB
});
</details>
Gotcha's
Problems with reading strings using StreamReader in while header
When publishing or compiling in Release mode, the <code>Optimize</code> flag is set by default. Compiling with this flag set may result in problems if you are using <code>StreamReader</code>. An bug is open on this subject, being investigated by the mono team. Tracked locally here. A simple workaround is available in this issue. Basically, don't call await in the while header, call it somewhere else. This has been fixed in Blazor 5rc1.
IFileReference.CreateMemoryStreamAsync()
The IFileReference.CreateMemoryStreamAsync() method (without any argument) is basically the same as calling IFileReference.CreateMemoryStreamAsync(bufferSize: file.Size).
Calling IFileReference.CreateMemoryStreamAsync() may thus be unsuitable for large files (at least for client-side Blazor as the UI will be blocked during the transfer).
Usage in a Blazor View
The code for views looks the same for both client- and server-side projects. The demo projects also contains a drag and drop example. While the demo projects are the reference, examples also exist in the wiki.
@page "/MyPage"
@using Tewr.Blazor.FileReader
@using System.IO;
@inject IFileReaderService fileReaderService;
<input type="file" @ref=inputTypeFileElement /><button @onclick=ReadFile>Read file</button>
@code
{
private ElementReference inputTypeFileElement;
public async Task ReadFile()
{
foreach (var file in await fileReaderService.CreateReference(inputTypeFileElement).EnumerateFilesAsync())
{
// Read into buffer and act (uses less memory)
await using (Stream stream = await file.OpenReadAsync()) {
// Do (async) stuff with stream...
await stream.ReadAsync(buffer, ...);
// The following will fail. Only async read is allowed.
stream.Read(buffer, ...)
}
// Read file fully into memory and act
using (MemoryStream memoryStream = await file.CreateMemoryStreamAsync(4096)) {
// Sync calls are ok once file is in memory
memoryStream.Read(buffer, ...)
}
}
}
}
Version notes
Version <code>3.4.0.24340</code> Adds dotnet9 support
Version <code>3.3.2.23201</code> Fixes a <a href="https://github.com/Tewr/BlazorFileReader/issues/194">a bug</a> in 3.3.2.23185 related to drag and drop
Version <code>3.3.2.23185</code> Adds the possibility to drop multiple files and directories on elements.
Version <code>3.3.1.21360</code> Fixes <a href="https://github.com/Tewr/BlazorFileReader/issues/186">a bug</a> related to platform detection under .net6
Version <code>3.3.0.21348</code> Adds .Net6 support.
Version <code>3.2.0.21211</code> Adds Copy/Paste support.
Version <code>3.1.0.21158</code> Adds two new methods (.NET5 only): JsObjectReference for files, and CreateObjectUrl for files (built on JsObjectReference). Adds a new overload for IFileReaderRef.RegisterDropEventsAsync that provides extensibility points for custom scripts.
Version <code>3.0.0.20340</code> Add support for .NET5 and fixes a small issue with Platform detection.
<details><summary>Older versions</summary> <details><summary>Version <code>2.1.0.20274</code></summary> WASM/CSB: Fixes a problem with large files and small buffer sizes. Server-side/SSB: Simplifies Setup, removes need for SignalR max size setting (`MaximumReceiveMessageSize`). It is recommended to remove the modification of this value, if present. Adds multithreaded fetch & message chunking for SignalR.</details> <details><summary>Version <code>2.0.0.20242</code></summary> Fixes a bug when working with file larger than 2Gb in InteropStream.Seek (#153)</details> <details><summary>Version <code>2.0.0.20200</code></summary> ⚠️ Breaking changes: Changes Root Namespace from `Blazor.FileReader` to `Tewr.Blazor.FileReader` to avoid conflicts. - `CancellationToken` can now be used in most relevant methods to cancel ongoing upload. - Native support for displaying progress. See <a href="/src/Demo/Blazor.FileReader.Demo.Common/IndexCommon.razor#L74">demo project</a> for usage.</details> <details><summary>Version <code>1.6.0.20166</code></summary> Fixes a <a href="https://github.com/Tewr/BlazorFileReader/issues/139">a memory allocation bug</a> (before this fix - since <code>v1.3.0.20033</code> - the browser would allocate the whole file in ram). Also, introduces a new collection property on <code>File</code> for non-standard properties (thanks to <a href="https://github.com/DouglasDwyer/">@DouglasDwyer</a> for idea and implementation)</details> <details><summary>Version <code>1.5.0.20109</code></summary> Fixes a <a href="https://github.com/Tewr/BlazorFileReader/issues/124">a minor bug</a> in drag and drop (before this fix, could not drop on chilRelated Skills
node-connect
344.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
99.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
