48 lines
1.5 KiB
C#
48 lines
1.5 KiB
C#
using Microsoft.AspNetCore.Hosting;
|
|
using NexusReader.Application.Abstractions.Services;
|
|
|
|
namespace NexusReader.Infrastructure.Services;
|
|
|
|
/// <summary>
|
|
/// Infrastructure implementation of general storage utilizing local filesystem.
|
|
/// Files are saved in wwwroot/uploads/media.
|
|
/// </summary>
|
|
public class LocalStorageService : IStorageService
|
|
{
|
|
private readonly IWebHostEnvironment _environment;
|
|
|
|
public LocalStorageService(IWebHostEnvironment environment)
|
|
{
|
|
_environment = environment;
|
|
}
|
|
|
|
public async Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string contentType)
|
|
{
|
|
using var stream = new MemoryStream(fileBytes);
|
|
return await UploadFileAsync(stream, fileName, contentType);
|
|
}
|
|
|
|
public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType)
|
|
{
|
|
var mediaFolder = Path.Combine(_environment.WebRootPath, "uploads", "media");
|
|
|
|
if (!Directory.Exists(mediaFolder))
|
|
{
|
|
Directory.CreateDirectory(mediaFolder);
|
|
}
|
|
|
|
// Clean file name to prevent path traversal issues
|
|
var safeFileName = Path.GetFileName(fileName);
|
|
var uniqueFileName = $"{Guid.NewGuid()}_{safeFileName}";
|
|
var filePath = Path.Combine(mediaFolder, uniqueFileName);
|
|
|
|
using (var outputStream = new FileStream(filePath, FileMode.Create))
|
|
{
|
|
await fileStream.CopyToAsync(outputStream);
|
|
}
|
|
|
|
// Return the public web-relative URL
|
|
return $"/uploads/media/{uniqueFileName}";
|
|
}
|
|
}
|