简体   繁体   English

blazor 服务器文件上传静默使服务器崩溃

[英]blazor server file upload silently crashes server

I'm testing image upload on my blazor server application.我正在我的 blazor 服务器应用程序上测试图像上传。 For this, my .razor component looks like this:为此,我的.razor组件如下所示:

@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:我将代码隐藏在一个单独的.razor.cs文件中,该类如下所示:

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.由于某些原因,在UploadImages()函数执行后,应用程序会静默崩溃。 I can't find anything useful in the console output nor are any exceptions thrown, it just stops with code -1.我在控制台输出中找不到任何有用的东西,也没有抛出任何异常,它只是以代码-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.该代码当前将文件存储在wwwroot文件夹中,我确信这是一个坏主意。 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?IBrowserFile对象提供给单独的类库是否常见? 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:编辑在我的浏览器的 Dev-Options 中,我收到以下错误:

Error: Connection disconnected with error 'Error: WebSocket closed with status code: 1006 ().'.错误:连接因错误“错误:WebSocket 关闭,状态码:1006 ()。”而断开连接。

as soon as I select any file for upload.只要我选择要上传的任何文件。 I tested different things (with/without authorization, calling/not calling the UploadImages() functions, etc...)我测试了不同的东西(有/无授权,调用/不调用UploadImages()函数等...)

I stumbled across that issue: Blazor Server inputfile Crashes with certain Chromium Based Browsers我偶然发现了这个问题: Blazor Server inputfile Crashs 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要进一步证明该理论,请下载以下代码: https ://github.com/mu88/StackOverflow_BlazorServerFileUpload
That's basically a simplified copy of your code which works on my machine in Chrome and Firefox.这基本上是您的代码的简化副本,可以在我的 Chrome 和 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.如果你可以在你的机器上用 Chrome 和 Firefox 运行该代码,但不能在 Brave 中运行,我想我们可以确定我们找到了罪魁祸首。

I was getting the same error in Google Chrome running a server-side Blazor project.我在运行服务器端Blazor 项目的 Google Chrome 中遇到了同样的错误。 Inside my appsettings.Development.json, I set all of my logging levels to debug before finally finding this error inside Visual Studio > Output:在我的 appsettings.Development.json 中,我将所有日志记录级别设置为调试,然后最终在 Visual Studio > 输出中找到此错误:

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:解决方案是进入您的 Program.cs 并添加以下集线器选项:

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);
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM