Logs for blob storage and some improvements
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.3" />
|
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.3" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.3" />
|
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.3" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
|
<PackageVersion Include="MinimalApis.Extensions" Version="0.11.0" />
|
||||||
<PackageVersion Include="Moq" Version="4.20.69" />
|
<PackageVersion Include="Moq" Version="4.20.69" />
|
||||||
<PackageVersion Include="NSwag.AspNetCore" Version="14.0.3" />
|
<PackageVersion Include="NSwag.AspNetCore" Version="14.0.3" />
|
||||||
<PackageVersion Include="NSwag.MSBuild" Version="14.0.3" />
|
<PackageVersion Include="NSwag.MSBuild" Version="14.0.3" />
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
|
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
|
||||||
<PackageReference Include="Google.Apis.Oauth2.v2" />
|
<PackageReference Include="Google.Apis.Oauth2.v2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
||||||
|
<PackageReference Include="MinimalApis.Extensions" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ public class Result<T>(
|
|||||||
return Value ?? default(T)!;
|
return Value ?? default(T)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetErrorsAsString()
|
||||||
|
{
|
||||||
|
return Errors.Length == 0 ? string.Empty : string.Join(", ", Errors);
|
||||||
|
}
|
||||||
|
|
||||||
public static Result<T> Success(T value)
|
public static Result<T> Success(T value)
|
||||||
{
|
{
|
||||||
return new Result<T>(value, true, Array.Empty<string>());
|
return new Result<T>(value, true, Array.Empty<string>());
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Hutopy.Application.Users.Commands;
|
namespace Hutopy.Application.Users.Commands;
|
||||||
public record CreateUserCommand : IRequest<Guid>
|
public record CreateUserCommand : IRequest<IResult>
|
||||||
{
|
{
|
||||||
public required string FirstName { get; init; }
|
public required string FirstName { get; init; }
|
||||||
public required string LastName { get; init; }
|
public required string LastName { get; init; }
|
||||||
@@ -10,7 +11,7 @@ public record CreateUserCommand : IRequest<Guid>
|
|||||||
public required string Password { get; init; }
|
public required string Password { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, Guid>
|
public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, IResult>
|
||||||
{
|
{
|
||||||
private readonly IApplicationDbContext _context;
|
private readonly IApplicationDbContext _context;
|
||||||
private readonly IIdentityService _identityService;
|
private readonly IIdentityService _identityService;
|
||||||
@@ -21,7 +22,7 @@ public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, Guid>
|
|||||||
_identityService = identityService;
|
_identityService = identityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Guid> Handle(CreateUserCommand request, CancellationToken cancellationToken)
|
public async Task<IResult> Handle(CreateUserCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await _identityService.CreateUserAsync(request.EmailAddress, request.UserName, request.FirstName, request.LastName, request.Password);
|
await _identityService.CreateUserAsync(request.EmailAddress, request.UserName, request.FirstName, request.LastName, request.Password);
|
||||||
|
|
||||||
@@ -29,6 +30,6 @@ public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, Guid>
|
|||||||
|
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
return new Guid(user?.Id ?? string.Empty);
|
return Results.Ok(new Guid(user?.Id ?? string.Empty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
using Hutopy.Application.Common.Models;
|
using Hutopy.Application.Common.Models;
|
||||||
using Hutopy.Application.Users.Models;
|
using Hutopy.Application.Users.Models;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Hutopy.Application.Users.Commands;
|
namespace Hutopy.Application.Users.Commands;
|
||||||
|
|
||||||
public class UpdateCurrentUserCommand : IRequest<string>
|
public class UpdateCurrentUserCommand : IRequest<IResult>
|
||||||
{
|
{
|
||||||
public required string FirstName { get; init; }
|
public required string FirstName { get; init; }
|
||||||
public required string LastName { get; init; }
|
public required string LastName { get; init; }
|
||||||
@@ -32,13 +33,13 @@ public class UpdateCurrentUserCommand : IRequest<string>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class UpdateCurrentUserCommandHandler(IApplicationDbContext context, IIdentityService identityService, IMapper mapper) :
|
public class UpdateCurrentUserCommandHandler(IApplicationDbContext context, IIdentityService identityService, IMapper mapper) :
|
||||||
IRequestHandler<UpdateCurrentUserCommand, string>
|
IRequestHandler<UpdateCurrentUserCommand, IResult>
|
||||||
{
|
{
|
||||||
public async Task<string> Handle(UpdateCurrentUserCommand request, CancellationToken cancellationToken)
|
public async Task<IResult> Handle(UpdateCurrentUserCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var identityUser = await identityService.GetCurrentUserAsync();
|
var identityUser = await identityService.GetCurrentUserAsync();
|
||||||
|
|
||||||
if (identityUser?.Id is null) return string.Empty;
|
if (identityUser?.Id is null) return Results.Problem("Current user not found.");
|
||||||
|
|
||||||
var userModel = mapper.Map<UserModel>(request);
|
var userModel = mapper.Map<UserModel>(request);
|
||||||
userModel.Id = identityUser.Id;
|
userModel.Id = identityUser.Id;
|
||||||
@@ -47,7 +48,7 @@ public class UpdateCurrentUserCommandHandler(IApplicationDbContext context, IIde
|
|||||||
|
|
||||||
await context.SaveChangesAsync(cancellationToken);
|
await context.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
return result.GetValueOrDefault();
|
return result.Succeeded ? Results.Ok(result.GetValueOrDefault()) : Results.Problem(result.GetErrorsAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,27 @@
|
|||||||
using Hutopy.Application.AzureBlobStorage.Constants;
|
using Hutopy.Application.AzureBlobStorage.Constants;
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Hutopy.Application.Users.Commands;
|
namespace Hutopy.Application.Users.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Upload a banner picture. If the user has the url already, set the BannerPictureUrl in the user only without upload.
|
/// Upload a banner picture. If the user has the url already, set the BannerPictureUrl in the user only without upload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UploadBannerPictureCommand : IRequest<string>
|
public class UploadBannerPictureCommand : IRequest<IResult>
|
||||||
{
|
{
|
||||||
public required Stream BannerPicture { get; init; }
|
public required Stream BannerPicture { get; init; }
|
||||||
public string BannerPictureUrl { get; init; } = string.Empty;
|
public string BannerPictureUrl { get; init; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UploadBannerPictureCommandHandler(IIdentityService identityService, IAzureBlobStorageService azureBlobStorageService) : IRequestHandler<UploadBannerPictureCommand, string>
|
public class UploadBannerPictureCommandHandler(IIdentityService identityService, IAzureBlobStorageService azureBlobStorageService) : IRequestHandler<UploadBannerPictureCommand, IResult>
|
||||||
{
|
{
|
||||||
public async Task<string> Handle(UploadBannerPictureCommand request, CancellationToken cancellationToken)
|
public async Task<IResult> Handle(UploadBannerPictureCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
// If an url to the picture is provided, use it right away and don't upload anything.
|
||||||
if (!string.IsNullOrEmpty(request.BannerPictureUrl))
|
if (!string.IsNullOrEmpty(request.BannerPictureUrl))
|
||||||
{
|
{
|
||||||
await identityService.UpdateCurrentUserBannerPictureUrlAsync(request.BannerPictureUrl);
|
await identityService.UpdateCurrentUserBannerPictureUrlAsync(request.BannerPictureUrl);
|
||||||
return request.BannerPictureUrl;
|
return Results.Ok(request.BannerPictureUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
var identityUser = await identityService.GetCurrentUserAsync();
|
var identityUser = await identityService.GetCurrentUserAsync();
|
||||||
@@ -27,11 +29,22 @@ public class UploadBannerPictureCommandHandler(IIdentityService identityService,
|
|||||||
|
|
||||||
var blobName = $"{currentUserId}/{SubDirectoryNames.Profile}/{CommonFileNames.BannerPicture}";
|
var blobName = $"{currentUserId}/{SubDirectoryNames.Profile}/{CommonFileNames.BannerPicture}";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
var url = await azureBlobStorageService.UploadFileAsync(ContainerNames.Users, blobName, request.BannerPicture, ContentTypes.ImagePng);
|
var url = await azureBlobStorageService.UploadFileAsync(ContainerNames.Users, blobName, request.BannerPicture, ContentTypes.ImagePng);
|
||||||
|
|
||||||
await identityService.UpdateCurrentUserBannerPictureUrlAsync(url);
|
await identityService.UpdateCurrentUserBannerPictureUrlAsync(url);
|
||||||
|
|
||||||
return url;
|
return Results.Ok(url);
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex)
|
||||||
|
{
|
||||||
|
return Results.BadRequest(ex.Message);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return Results.StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,27 @@
|
|||||||
using Hutopy.Application.AzureBlobStorage.Constants;
|
using Hutopy.Application.AzureBlobStorage.Constants;
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Hutopy.Application.Users.Commands;
|
namespace Hutopy.Application.Users.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Upload a profile picture. If the user has the url already, set the ProfilePictureUrl in the user only without upload.
|
/// Upload a profile picture. If the user has the url already, set the ProfilePictureUrl in the user only without upload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UploadProfilePictureCommand : IRequest<string>
|
public class UploadProfilePictureCommand : IRequest<IResult>
|
||||||
{
|
{
|
||||||
public required Stream ProfilePicture { get; init; }
|
public required Stream ProfilePicture { get; init; }
|
||||||
public string ProfilePictureUrl { get; init; } = string.Empty;
|
public string ProfilePictureUrl { get; init; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UploadProfilePictureCommandHandler(IIdentityService identityService, IAzureBlobStorageService azureBlobStorageService) : IRequestHandler<UploadProfilePictureCommand, string>
|
public class UploadProfilePictureCommandHandler(IIdentityService identityService, IAzureBlobStorageService azureBlobStorageService) : IRequestHandler<UploadProfilePictureCommand, IResult>
|
||||||
{
|
{
|
||||||
public async Task<string> Handle(UploadProfilePictureCommand request, CancellationToken cancellationToken)
|
public async Task<IResult> Handle(UploadProfilePictureCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
// If an url to the picture is provided, use it right away and don't upload anything.
|
||||||
if (!string.IsNullOrEmpty(request.ProfilePictureUrl))
|
if (!string.IsNullOrEmpty(request.ProfilePictureUrl))
|
||||||
{
|
{
|
||||||
await identityService.UpdateCurrentUserProfilePictureUrlAsync(request.ProfilePictureUrl);
|
await identityService.UpdateCurrentUserProfilePictureUrlAsync(request.ProfilePictureUrl);
|
||||||
return request.ProfilePictureUrl;
|
return Results.Ok(request.ProfilePictureUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
var identityUser = await identityService.GetCurrentUserAsync();
|
var identityUser = await identityService.GetCurrentUserAsync();
|
||||||
@@ -31,7 +33,7 @@ public class UploadProfilePictureCommandHandler(IIdentityService identityService
|
|||||||
|
|
||||||
await identityService.UpdateCurrentUserProfilePictureUrlAsync(url);
|
await identityService.UpdateCurrentUserProfilePictureUrlAsync(url);
|
||||||
|
|
||||||
return url;
|
return Results.Ok(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,28 @@
|
|||||||
using Hutopy.Application.AzureBlobStorage.Constants;
|
using Hutopy.Application.AzureBlobStorage.Constants;
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Hutopy.Application.Users.Commands;
|
namespace Hutopy.Application.Users.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Upload a website icon. If the user has the url already, set the WebsitePictureUrl in the user only without upload.
|
/// Upload a website icon. If the user has the url already, set the WebsitePictureUrl in the user only without upload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UploadWebsiteIconCommand : IRequest<string>
|
public class UploadWebsiteIconCommand : IRequest<IResult>
|
||||||
{
|
{
|
||||||
public required Stream WebsiteIcon { get; init; }
|
public required Stream WebsiteIcon { get; init; }
|
||||||
|
|
||||||
public string WebsitePictureUrl { get; init; } = string.Empty;
|
public string WebsitePictureUrl { get; init; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UploadWebsiteIconCommandHandler(IIdentityService identityService, IAzureBlobStorageService azureBlobStorageService) : IRequestHandler<UploadWebsiteIconCommand, string>
|
public class UploadWebsiteIconCommandHandler(IIdentityService identityService, IAzureBlobStorageService azureBlobStorageService) : IRequestHandler<UploadWebsiteIconCommand, IResult>
|
||||||
{
|
{
|
||||||
public async Task<string> Handle(UploadWebsiteIconCommand request, CancellationToken cancellationToken)
|
public async Task<IResult> Handle(UploadWebsiteIconCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
// If an url to the picture is provided, use it right away and don't upload anything.
|
||||||
if (!string.IsNullOrEmpty(request.WebsitePictureUrl))
|
if (!string.IsNullOrEmpty(request.WebsitePictureUrl))
|
||||||
{
|
{
|
||||||
await identityService.UpdateCurrentUserWebsiteIconUrlAsync(request.WebsitePictureUrl);
|
await identityService.UpdateCurrentUserWebsiteIconUrlAsync(request.WebsitePictureUrl);
|
||||||
return request.WebsitePictureUrl;
|
return Results.Ok(request.WebsitePictureUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
var identityUser = await identityService.GetCurrentUserAsync();
|
var identityUser = await identityService.GetCurrentUserAsync();
|
||||||
@@ -32,7 +34,7 @@ public class UploadWebsiteIconCommandHandler(IIdentityService identityService, I
|
|||||||
|
|
||||||
await identityService.UpdateCurrentUserWebsiteIconUrlAsync(url);
|
await identityService.UpdateCurrentUserWebsiteIconUrlAsync(url);
|
||||||
|
|
||||||
return url;
|
return Results.Ok(request.WebsitePictureUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Azure;
|
||||||
using Azure.Storage.Blobs;
|
using Azure.Storage.Blobs;
|
||||||
using Azure.Storage.Blobs.Models;
|
using Azure.Storage.Blobs.Models;
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Hutopy.Infrastructure.AzureBlob;
|
namespace Hutopy.Infrastructure.AzureBlob;
|
||||||
|
|
||||||
public class AzureBlobStorageService : IAzureBlobStorageService
|
public class AzureBlobStorageService : IAzureBlobStorageService
|
||||||
{
|
{
|
||||||
private readonly BlobServiceClient _blobServiceClient;
|
private readonly BlobServiceClient _blobServiceClient;
|
||||||
|
private readonly ILogger<AzureBlobStorageService> _logger;
|
||||||
|
private readonly long _maxUploadSize = 10 * 1024 * 1024; // 10 MB in bytes
|
||||||
|
|
||||||
public AzureBlobStorageService(IConfiguration configuration)
|
|
||||||
|
public AzureBlobStorageService(IConfiguration configuration, ILogger<AzureBlobStorageService> logger)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
var connectionString = configuration["Azure-Blob-Connection-String"] ?? "";
|
var connectionString = configuration["Azure-Blob-Connection-String"] ?? "";
|
||||||
_blobServiceClient = new BlobServiceClient(connectionString);
|
_blobServiceClient = new BlobServiceClient(connectionString);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -28,6 +33,21 @@ public class AzureBlobStorageService : IAzureBlobStorageService
|
|||||||
/// <param name="contentType">The content type.</param>
|
/// <param name="contentType">The content type.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<string> UploadFileAsync(string containerName, string blobName, Stream fileStream, string contentType)
|
public async Task<string> UploadFileAsync(string containerName, string blobName, Stream fileStream, string contentType)
|
||||||
|
{
|
||||||
|
// Read the file stream into a memory stream to determine the length
|
||||||
|
// WATCH FOR MEMORY USAGE USING THE MEMORY STREAM.
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
await fileStream.CopyToAsync(memoryStream);
|
||||||
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
// Check if the file size exceeds the maximum upload size
|
||||||
|
if (memoryStream.Length > _maxUploadSize)
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"Blob storage: File size exceeds the maximum allowed size of {_maxUploadSize} bytes.");
|
||||||
|
throw new InvalidOperationException($"Blob storage: File size exceeds the maximum allowed size of {_maxUploadSize} bytes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Get a reference to a container
|
// Get a reference to a container
|
||||||
var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
|
var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
|
||||||
@@ -45,13 +65,34 @@ public class AzureBlobStorageService : IAzureBlobStorageService
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Upload the file
|
// Upload the file
|
||||||
await blobClient.UploadAsync(fileStream, new BlobUploadOptions
|
var response = await blobClient.UploadAsync(memoryStream, new BlobUploadOptions
|
||||||
{
|
{
|
||||||
HttpHeaders = blobHttpHeaders
|
HttpHeaders = blobHttpHeaders
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var fileUri = blobClient.Uri.ToString();
|
||||||
|
|
||||||
|
_logger.LogInformation(
|
||||||
|
$"Blob storage: Status [ {response.GetRawResponse().Status.ToString()} ] " +
|
||||||
|
$"Uploaded [ {blobName} ] to the container [ {containerName} ] " +
|
||||||
|
$"with contentType [ {contentType} ] " +
|
||||||
|
$"with a length of [ {memoryStream.Length} bytes ]" +
|
||||||
|
$"with the uri [ {fileUri} ]"
|
||||||
|
);
|
||||||
|
|
||||||
// Return the URI of the uploaded blob
|
// Return the URI of the uploaded blob
|
||||||
return blobClient.Uri.ToString();
|
return fileUri;
|
||||||
|
}
|
||||||
|
catch (RequestFailedException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Blob storage: Azure Storage request failed: {ex.Message}");
|
||||||
|
throw new Exception("Error uploading file to Azure Blob Storage", ex);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Blob storage: An error occurred: {ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -61,6 +102,8 @@ public class AzureBlobStorageService : IAzureBlobStorageService
|
|||||||
/// <param name="containerName">The name of the container where the file is stored. (users)</param>
|
/// <param name="containerName">The name of the container where the file is stored. (users)</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<MemoryStream> DownloadFileAsync(string containerName, string blobName)
|
public async Task<MemoryStream> DownloadFileAsync(string containerName, string blobName)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Get a reference to a container
|
// Get a reference to a container
|
||||||
var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
|
var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
|
||||||
@@ -68,8 +111,6 @@ public class AzureBlobStorageService : IAzureBlobStorageService
|
|||||||
// Get a reference to a blob
|
// Get a reference to a blob
|
||||||
var blobClient = containerClient.GetBlobClient(blobName);
|
var blobClient = containerClient.GetBlobClient(blobName);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Download the blob to a stream
|
// Download the blob to a stream
|
||||||
BlobDownloadInfo download = await blobClient.DownloadAsync();
|
BlobDownloadInfo download = await blobClient.DownloadAsync();
|
||||||
MemoryStream memoryStream = new();
|
MemoryStream memoryStream = new();
|
||||||
@@ -78,9 +119,14 @@ public class AzureBlobStorageService : IAzureBlobStorageService
|
|||||||
|
|
||||||
return memoryStream;
|
return memoryStream;
|
||||||
}
|
}
|
||||||
|
catch (RequestFailedException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Azure Storage request failed: {ex.Message}");
|
||||||
|
throw new Exception("Error downloading file from Azure Blob Storage", ex);
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Log and handle the exception as needed
|
_logger.LogError($"An error occurred: {ex.Message}");
|
||||||
throw new ApplicationException("Error downloading file from Azure Blob Storage.", ex);
|
throw new ApplicationException("Error downloading file from Azure Blob Storage.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,24 +14,24 @@ public class UpdateMyUser : EndpointGroupBase
|
|||||||
.MapPatch("/profile", UpdateCurrentUser);
|
.MapPatch("/profile", UpdateCurrentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> UpdateCurrentUser(ISender sender, UpdateCurrentUserCommand command)
|
private static async Task<IResult> UpdateCurrentUser(ISender sender, UpdateCurrentUserCommand command)
|
||||||
{
|
{
|
||||||
return await sender.Send(command);
|
return await sender.Send(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> UpdateCurrentUserProfilePicture(ISender sender, Stream stream, string url = "")
|
private static async Task<IResult> UpdateCurrentUserProfilePicture(ISender sender, Stream stream, string url = "")
|
||||||
{
|
{
|
||||||
var command = new UploadProfilePictureCommand { ProfilePicture = stream, ProfilePictureUrl = url};
|
var command = new UploadProfilePictureCommand { ProfilePicture = stream, ProfilePictureUrl = url};
|
||||||
return await sender.Send(command);
|
return await sender.Send(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> UpdateCurrentUserBannerPicture(ISender sender, Stream stream, string url = "")
|
private static async Task<IResult> UpdateCurrentUserBannerPicture(ISender sender, Stream stream, string url = "")
|
||||||
{
|
{
|
||||||
var command = new UploadBannerPictureCommand { BannerPicture = stream, BannerPictureUrl = url};
|
var command = new UploadBannerPictureCommand { BannerPicture = stream, BannerPictureUrl = url};
|
||||||
return await sender.Send(command);
|
return await sender.Send(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> UpdateCurrentUserWebsiteIcon(ISender sender, Stream stream, string url = "")
|
private static async Task<IResult> UpdateCurrentUserWebsiteIcon(ISender sender, Stream stream, string url = "")
|
||||||
{
|
{
|
||||||
var command = new UploadWebsiteIconCommand { WebsiteIcon = stream, WebsitePictureUrl = url};
|
var command = new UploadWebsiteIconCommand { WebsiteIcon = stream, WebsitePictureUrl = url};
|
||||||
return await sender.Send(command);
|
return await sender.Send(command);
|
||||||
|
|||||||
@@ -10,11 +10,10 @@ public class Users : EndpointGroupBase
|
|||||||
app.MapGroup(this)
|
app.MapGroup(this)
|
||||||
.MapPost(CreateUser)
|
.MapPost(CreateUser)
|
||||||
.MapPost(Login, "/login")
|
.MapPost(Login, "/login")
|
||||||
.MapPost(UploadProfilePicture, "/upload-profile-picture")
|
|
||||||
.MapGet(GetUser);
|
.MapGet(GetUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Guid> CreateUser(ISender sender, CreateUserCommand command)
|
private static async Task<IResult> CreateUser(ISender sender, CreateUserCommand command)
|
||||||
{
|
{
|
||||||
return await sender.Send(command);
|
return await sender.Send(command);
|
||||||
}
|
}
|
||||||
@@ -28,11 +27,4 @@ public class Users : EndpointGroupBase
|
|||||||
{
|
{
|
||||||
return await sender.Send(command);
|
return await sender.Send(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> UploadProfilePicture(ISender sender, Stream stream)
|
|
||||||
{
|
|
||||||
var command = new UploadProfilePictureCommand { ProfilePicture = stream };
|
|
||||||
|
|
||||||
return await sender.Send(command);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user