4

I'm testing image upload on my blazor server application. For this, my .razor component looks like this:

@page "/uploadtest"

<h1>Upload Example</h1>
<AuthorizeView>
    <Authorized>
        <p>A simple example with a model, which can upload images</p>
        <label>
            Load Images:
            <InputFile OnChange="@UploadImages" multiple accept=".jpg,.jpeg,.png" />
        </label>

    </Authorized>
    <NotAuthorized>
        <p>To use this application, please <a href="Identity/Account/Login">log in</a> or <a href="Identity/Account/Register">register</a> a new account! </p>
    </NotAuthorized>
</AuthorizeView>

I put the code-behind in a separate .razor.cs file, the class looks like this:

public partial class UploadExample: ComponentBase
{ 
    #region Protected Properties
    [Inject]
    protected AuthenticationStateProvider AuthenticationStateProvider { get; private set; }

    [Inject]
    protected IWebHostEnvironment WebHostEnvironment { get; private set; }
    #endregion

    #region Public Methods
    /// <summary>
    /// File upload
    /// Only images of type .jpg and png are allowed here.
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    protected async Task UploadImages(InputFileChangeEventArgs ifc)
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            try
            {
                string userId = user.FindFirst(c => c.Type.Contains("nameidentifier"))?.Value;
                string currentTime = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss");
                string path = Path.Combine(WebHostEnvironment.WebRootPath, $@"UserData/{userId}/UploadTest/{currentTime}");
                Directory.CreateDirectory(path);
                var files = ifc.GetMultipleFiles();
                foreach (var file in files)
                {
                    var filePath = Path.Combine(path, file.Name);
                    await using FileStream fs = new(filePath, FileMode.Create);
                    await file.OpenReadStream().CopyToAsync(fs);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
    #endregion
}

Here are my issues:

  • For some reason after the UploadImages() function is executed, the application silently crashes. I can't find anything useful in the console output nor are any exceptions thrown, it just stops with code -1. The files however are successfully uploaded to the expected folder. Furthermore, the crash seems to be independent from the function.
  • The code currently stores the files in the wwwroot folder, which I am sure is a bad idea. I already have a data access layer, which is a separate class library and handles all the database stuff. Basically, I want only the path to the images stored in the database, but the data access library should still handle storage of the a images. Is it common to give IBrowserFile objects to a separate class library? If not, how would the data be sent to the data access layer?

Edit In the Dev-Options of my browser, I get the following error:

Error: Connection disconnected with error 'Error: WebSocket closed with status code: 1006 ().'.

as soon as I select any file for upload. I tested different things (with/without authorization, calling/not calling the UploadImages() functions, etc...)

11
  • What does the stack trace say? And instead of passing IBrowserFile around, I'd use a Stream Commented Feb 16, 2022 at 12:52
  • @mu88 give me a sec, I'll check. Another thing I just realized is, that the "silent crash" only happens on my default browser which is Brave, a Chromium based browser. On MS Edge, the issue doesn't seem to be apparent. Commented Feb 16, 2022 at 12:58
  • Problem is I can't really watch the call stack, since the program just..."exits". No exception is thrown. Also if I set a breakpoint in the method above, it is hit, but then immediately the whole program shuts down. Commented Feb 16, 2022 at 13:09
  • What is the last line of code you can reach without crashing the program? And is your code on GitHub? Commented Feb 16, 2022 at 13:12
  • Unfortuanely this is company code, so I can't share the whole project. Anyways, the problem is, that even I use <InputFile/> tag completely empty (meaning no attributes, no code called), the crash happens. Commented Feb 16, 2022 at 13:18

3 Answers 3

10

I stumbled across that issue: Blazor Server inputfile Crashes with certain Chromium Based Browsers
That sounds pretty much like what you're experiencing, right?

To further proof that theory, please download the following code: https://github.com/mu88/StackOverflow_BlazorServerFileUpload
That's basically a simplified copy of your code which works on my machine in Chrome and Firefox. If you can run that code on your machine in Chrome and Firefox, but not in Brave, I think we can be sure that we found the culprit.

Sign up to request clarification or add additional context in comments.

4 Comments

That's 3 hours of my live I won't get back^^ Anyway, I marked your answer as correct, since it will lead future users to the core of the issue directly :)
That's right 😁 but anyways, we've learned something - and be it only a bug ^^
Mine is happening in production and when debugging. Just started after updating from Net5 to Net 6.
More on this issue: stackoverflow.com/a/59611796
3

I was getting the same error in Google Chrome running a server-side Blazor project. Inside my appsettings.Development.json, I set all of my logging levels to debug before finally finding this error inside Visual Studio > Output:

Microsoft.AspNetCore.SignalR.HubConnectionHandler: Debug: Error when processing requests.

System.IO.InvalidDataException: The maximum message size of 32768B was exceeded. The message size can be configured in AddHubOptions.
    at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.DispatchMessagesAsync(HubConnectionContext connection)
    at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)

The solution is to go into your Program.cs and add the following hub option:

builder.Services.AddServerSideBlazor().AddHubOptions(options =>
{
    // maximum message size of 2MB
    options.MaximumReceiveMessageSize = 2000000;
});

Here's a sample of my image upload code, which I didn't need to change:

// maximum message size of 2MB
using (Stream stream = args.File.OpenReadStream(2000000))
{
    await using (MemoryStream memoryStream = new MemoryStream())
    {
        await stream.CopyToAsync(memoryStream);

        imageBuffer = memoryStream.ToArray();
    }

    string base64 = Convert.ToBase64String(imageBuffer);
    ...
}

1 Comment

It's better to use 2 * 1024 * 1024 for you 2MB
3

I came across this post after spending hours debugging a very similar issue with Radzen Blazor (Server-Side) file upload. If anyone else lands here: this is not an actual crash of your app, but rather a quirk of the Visual Studio debugger getting detached after closing the file picker in certain Chromium-based browsers (like Vivaldi, sometimes Chrome or Opera).
If you run your app with Microsoft Edge, the problem does not occur.
So if your app "crashes" after file selection but works fine otherwise, try switching the debug browser to Edge or launching the app manually outside of the debugger.

Hope this saves someone else a headache!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.