raysefo
raysefo

Reputation: 472

Blazor Server .NET 8 multiple image upload problem

I am trying to upload multiple images, but getting this weird error while uploading the second image whatever I tried I couldn't manage.

Here is my razor page method which gets the images:

private async Task HandleImageUpload(InputFileChangeEventArgs e)
{
    IsLoading = true;
    try
    {
        var files = e.GetMultipleFiles();

        var validFiles = new List<IBrowserFile>();

        foreach (var file in files)
        {
            var fileInfo = new System.IO.FileInfo(file.Name);
            if (fileInfo.Extension.ToLower() == ".jpg" ||
                fileInfo.Extension.ToLower() == ".png" ||
                fileInfo.Extension.ToLower() == ".jpeg")
            {
                validFiles.Add(file);
            }
            else
            {
                await _jsRuntime.ToastrError("Please select .jpg/.jpeg/.png file only");
                IsLoading = false;
                return;
            }
        }

        var imageUrls = await _fileUpload.UploadFiles(validFiles);
        Product.ImageUrls.AddRange(imageUrls);
    }
    catch (Exception ex)
    {
        await _jsRuntime.ToastrError(ex.Message);
    }
    finally
    {
        IsLoading = false;
    }
}

Here is the service I am trying to upload images:

public async Task<List<string>> UploadFiles(IEnumerable<IBrowserFile> files)
{
    var filePaths = new List<string>();

    try
    {
        foreach (var file in files)
        {
            var fullPath = "";
            FileInfo fileInfo = new(file.Name);
            var fileName = Guid.NewGuid().ToString() + fileInfo.Extension;
            var folderDirectory = $"{_webHostEnvironment.WebRootPath}\\images\\product";

            if (!Directory.Exists(folderDirectory))
            {
                Directory.CreateDirectory(folderDirectory);
            }

            var filePath = Path.Combine(folderDirectory, fileName);

            await using var fs = new FileStream(filePath, FileMode.Create);
            await file.OpenReadStream(MaxFileSize).CopyToAsync(fs);

            fullPath = $"/images/product/{fileName}";
            filePaths.Add(fullPath);
        }

        return filePaths;
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

Max file size is 30MB and the images I am trying to upload are 2MB total.

Screenshot

Here is the weird error I am getting:

Microsoft.JSInterop.JSException
  HResult=0x80131500
  Message=e is null
Qe@http://localhost:7253/_framework/blazor.server.js:1:37025
readFileData@http://localhost:7253/_framework/blazor.server.js:1:36985
beginInvokeJSFromDotNet/s<@http://localhost:7253/_framework/blazor.server.js:1:3047
beginInvokeJSFromDotNet@http://localhost:7253/_framework/blazor.server.js:1:3004
_invokeClientMethod@http://localhost:7253/_framework/blazor.server.js:1:60890
_processIncomingData@http://localhost:7253/_framework/blazor.server.js:1:58279
Xt/this.connection.onreceive@http://localhost:7253/_framework/blazor.server.js:1:51920
connect/</s.onmessage@http://localhost:7253/_framework/blazor.server.js:1:80026

  Source=System.Private.CoreLib
  StackTrace:
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.<OpenReadStreamAsync>d__29.MoveNext()
   at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.<CopyFileDataIntoBuffer>d__30.MoveNext()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.<ReadAsync>d__28.MoveNext()
   at System.IO.Stream.<<CopyToAsync>g__Core|27_0>d.MoveNext()
   at Web_Server.Service.FileUpload.<UploadFiles>d__5.MoveNext() in C:\Users\197199\Desktop\E-Commerce\Blazor-master\Web_Server\Service\FileUpload.cs:line 93

  This exception was originally thrown at this call stack:
    [External Code]
    Web_Server.Service.FileUpload.UploadFiles(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Components.Forms.IBrowserFile>) in FileUpload.cs

I searched but couldn't find a way to fix this issue. Hope you guys can help me.

Note: It was a .net6 Blazor Server application, I changed it target framework to .net8.

Update:

I added "Microsoft.AspNetCore.SignalR": "Debug" to appsettings.Development.json.

Added HubOptions to Program.cs:

builder.Services.AddSignalR(hubOptions =>
{
    hubOptions.EnableDetailedErrors = true;
    hubOptions.MaximumReceiveMessageSize = 1024 * 1024 * 20;
});

Here is the SignalR message I am getting:

Uploading file: jpeg-optimizer_s-l1602-removebg-preview.png, Size: 5048, Path: C:\Users\197199\Desktop\E-Commerce\TangyBlazor-master\TangyWeb_Server\wwwroot\images\product\d4274f9e-b04b-435d-9773-5bc9b4af57ed.png
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 108, True, [108,true,{"__jsStreamReferenceLength":5048,"__jsObjectId":1}] ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 109, True, [109,true,null] ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 110, True, [110,true,null] ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 111, True, [111,true,null] ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 112, True, [112,true,null] ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "OnRenderCompleted", Arguments: [ 16,  ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 113, True, [113,true,null] ], StreamIds: [  ] }.
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "ReceiveJSDataChunk", Arguments: [ 0, 0, System.Byte[],  ], StreamIds: [  ] }.
Uploading file: jpeg-optimizer_s-l1603-removebg-preview.png, Size: 7382, Path: C:\Users\197199\Desktop\E-Commerce\TangyBlazor-master\TangyWeb_Server\wwwroot\images\product\9e2d026c-43b1-4f34-96c4-4b44d9127e9a.png
dbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1]
      Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 114, False, [114,false,"e is null\nQe@http://localhost:7253/_framework/blazor.server.js:1:37025\nreadFileData@http://localhost:7253/_framework/blazor.server.js:1:36985\nbeginInvokeJSFromDotNet/s<@http://localhost:7253/_framework/blazor.server.js:1:3047\nbeginInvokeJSFromDotNet@http://localhost:7253/_framework/blazor.server.js:1:3004\n_invokeClientMethod@http://localhost:7253/_framework/blazor.server.js:1:60890\n_processIncomingData@http://localhost:7253/_framework/blazor.server.js:1:58279\nXt/this.connection.onreceive@http://localhost:7253/_framework/blazor.server.js:1:51920\nconnect/</s.onmessage@http://localhost:7253/_framework/blazor.server.js:1:80026\n"] ], StreamIds: [  ] }.

Update 2:

My project is Blazor Server, not Blazor Web App and the target framework is .net 8. Maybe it is due to render mode. How can I add InteractiveServerRenderMode?

Upvotes: 1

Views: 253

Answers (1)

raysefo
raysefo

Reputation: 472

After a lot of trial and error and tears the following code worked interestingly. I put this method on the razor page, not on the service.

//Remove old images
Product.ImageUrls.Clear();

foreach (var file in _selectedFiles)
{
    System.IO.FileInfo fileInfo = new(file.Name);
    var fileName = Guid.NewGuid().ToString() + fileInfo.Extension;
    var folderDirectory = $"{_webHostEnvironment.WebRootPath}\\images\\product";

    if (!Directory.Exists(folderDirectory))
    {
        Directory.CreateDirectory(folderDirectory);
    }

    var filePath = Path.Combine(folderDirectory, fileName);

    Stream stream = file.OpenReadStream();
    FileStream fs = File.Create(filePath);
    await stream.CopyToAsync(fs);
    stream.Close();
    fs.Close();

    _fullPath = $"/images/product/{fileName}";
    Product.ImageUrls.Add(_fullPath);
}

Upvotes: 0

Related Questions