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
wwwrootfolder, 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 giveIBrowserFileobjects 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...)
IBrowserFilearound, I'd use aStream<InputFile/>tag completely empty (meaning no attributes, no code called), the crash happens.