aspnetcore: Blazor WASM: File Upload - MultipartFormDataContent.Add() throws internal Invalid JSON exception
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Uploading a file results in Invalid JSON in internal code.
ImageUploader.razor:
<InputFile OnChange="UploadFiles" multiple />
ImageUploader.razor.cs:
using BlazorTests.Shared;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
namespace BlazorTests.Client.Shared
{
public partial class ImageUploader : ComponentBase
{
private List<File> files = new();
private List<UploadResult> uploadResults = new();
private int maxAllowedFiles = 10;
private bool shouldRender;
protected override bool ShouldRender() => shouldRender;
private void UploadFiles(InputFileChangeEventArgs e)
{
shouldRender = false;
long maxFileSize = 1024 * 1024 * 15;
var upload = false;
using var content = new MultipartFormDataContent();
foreach (var file in e.GetMultipleFiles(maxAllowedFiles))
{
if (uploadResults.SingleOrDefault(
f => f.FileName == file.Name) is null)
{
try
{
var fileContent =
new StreamContent(file.OpenReadStream(maxFileSize));
fileContent.Headers.ContentType =
new MediaTypeHeaderValue(file.ContentType);
files.Add(new() { Name = file.Name });
try // This is the block that throws. Note that the exception is not catched and the app breaks.
{
content.Add(
content: fileContent,
name: "\"files\"",
fileName: file.Name);
}catch(JsonException ex)
{
Console.WriteLine(ex.Message);
}
upload = true;
}
catch (Exception)
{
uploadResults.Add(
new()
{
FileName = file.Name,
ErrorCode = 6,
Uploaded = false
});
}
}
}
shouldRender = true;
}
private class File
{
public string Name { get; set; }
}
}
}
The code is taken from documentation.
Expected Behavior
No exception, obviously.
Steps To Reproduce
https://github.com/Grizzlly/BlazorTests
Exceptions (if any)
When I debug and try to upload a file, I get this:

.NET Version
6.0.100
Anything else?
.NET SDK (reflecting any global.json): Version: 6.0.100 Commit: 9e8b04bbff
Runtime Environment: OS Name: Windows OS Version: 10.0.22000 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.100\
Host (useful for support): Version: 6.0.0 Commit: 4822e3c3aa
.NET SDKs installed: 3.1.415 [C:\Program Files\dotnet\sdk] 5.0.104 [C:\Program Files\dotnet\sdk] 5.0.209 [C:\Program Files\dotnet\sdk] 5.0.303 [C:\Program Files\dotnet\sdk] 5.0.403 [C:\Program Files\dotnet\sdk] 6.0.100 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.0-rc.1.21451.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.0-rc.1.21451.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 36 (22 by maintainers)
Yes. The reason why that works isn’t because of
StringContentbut rather becauseawait fileContent.ReadAsStringAsync()ensures we await the streaming initialization.content: new StringContent(await fileContent.ReadAsStringAsync(), Encoding.UTF8, "application/octet-stream")Yes we’ll be discussing potentially bringing this into a future patch release in the new year once team members return from seasonal holidays. Fortunately it won’t affect everyone as those who do the actual upload end up reading the stream as well per the sample:
This is present in the official docs (but not in the sample you provided). This is likely also the explanation for why you and I were seeing this error reproduce, however Luke was not (as Luke was likely using the
FileUpload2component exactly as documented with the upload section).https://github.com/dotnet/aspnetcore/pull/39060 will ensure we don’t get the un-necessary exceptions, however the fact that we threw an exception in the first place in .NET 6 and not .NET 5 was bothering me. I wanted to make sure this wasn’t indicative of a deeper issue. Fortunately it’s not.
EndInvokeJSfailing as the pending task is missing. We throw an exception saying we haven’t read the contents of the call. This is what https://github.com/dotnet/aspnetcore/pull/39060 fixes.e.File.OpenReadStream()which requests the stream, and JS sends back the__jsStreamReferenceLengthand__jsObjectId. However in between the request and response, we cancel (ex. end of function or a variety of other reasons).I’ve minimized the repro to the following.
Exceptions from investigation
Stack trace on what’s removing the pending task:
Stack trace with args:
The issue is not with the DataContent, but rather calling
file.OpenReadStreamand then immediately cancelling the request (by not doing anything with the stream / letting the function terminate). If you don’t callfile.OpenReadStream(until you’re actually ready to read from the stream) you shouldn’t have this issue.From your original example:
This is not the block that throws (and hence why no exception is caught). The exception is thrown at the end of the function when things are GC’d.
Hmm this repro shouldn’t require MVC at all. You should just be able to do something in a clean wasm app (
dotnet new blazorwasm).Thank you! It is a bummer that this broke out of the blue as my app kinda depends on this… Let me know if you need any more info.
When published, even with offline mode enabled, I get this:
I will test without PWA (only HTTPS and ASP.NET Core hosted) tonight (in about 3-4 hours) and post the results.