94 lines
2.9 KiB
C#
94 lines
2.9 KiB
C#
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using MongoDB.Driver.GridFS;
|
|
|
|
namespace BCards.Web.Services;
|
|
|
|
public class GridFSDocumentStorage : IDocumentStorageService
|
|
{
|
|
private const int MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
private static readonly string[] ALLOWED_TYPES = { "application/pdf" };
|
|
|
|
private readonly GridFSBucket _gridFS;
|
|
private readonly ILogger<GridFSDocumentStorage> _logger;
|
|
|
|
public GridFSDocumentStorage(IMongoDatabase database, ILogger<GridFSDocumentStorage> logger)
|
|
{
|
|
_gridFS = new GridFSBucket(database, new GridFSBucketOptions
|
|
{
|
|
BucketName = "page_documents"
|
|
});
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<string> SaveDocumentAsync(byte[] documentBytes, string fileName, string contentType)
|
|
{
|
|
if (documentBytes == null || documentBytes.Length == 0)
|
|
throw new ArgumentException("Documento inválido.");
|
|
|
|
if (documentBytes.Length > MAX_FILE_SIZE)
|
|
throw new ArgumentException($"Arquivo muito grande. Tamanho máximo permitido: {MAX_FILE_SIZE / (1024 * 1024)}MB.");
|
|
|
|
if (!ALLOWED_TYPES.Contains(contentType.ToLower()))
|
|
throw new ArgumentException("Tipo de arquivo não suportado. Envie um PDF.");
|
|
|
|
var uniqueFileName = $"document_{DateTime.UtcNow:yyyyMMdd_HHmmss}_{Guid.NewGuid():N}.pdf";
|
|
|
|
var options = new GridFSUploadOptions
|
|
{
|
|
Metadata = new BsonDocument
|
|
{
|
|
{ "originalFileName", fileName },
|
|
{ "contentType", contentType },
|
|
{ "uploadDate", DateTime.UtcNow },
|
|
{ "size", documentBytes.Length }
|
|
}
|
|
};
|
|
|
|
var fileId = await _gridFS.UploadFromBytesAsync(uniqueFileName, documentBytes, options);
|
|
_logger.LogInformation("PDF salvo no GridFS: {FileId}", fileId);
|
|
return fileId.ToString();
|
|
}
|
|
|
|
public async Task<byte[]?> GetDocumentAsync(string documentId)
|
|
{
|
|
if (!ObjectId.TryParse(documentId, out var objectId))
|
|
return null;
|
|
|
|
try
|
|
{
|
|
return await _gridFS.DownloadAsBytesAsync(objectId);
|
|
}
|
|
catch (GridFSFileNotFoundException)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> DeleteDocumentAsync(string documentId)
|
|
{
|
|
if (!ObjectId.TryParse(documentId, out var objectId))
|
|
return false;
|
|
|
|
try
|
|
{
|
|
await _gridFS.DeleteAsync(objectId);
|
|
return true;
|
|
}
|
|
catch (GridFSFileNotFoundException)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<bool> DocumentExistsAsync(string documentId)
|
|
{
|
|
if (!ObjectId.TryParse(documentId, out var objectId))
|
|
return false;
|
|
|
|
var filter = Builders<GridFSFileInfo>.Filter.Eq("_id", objectId);
|
|
var fileInfo = await _gridFS.Find(filter).FirstOrDefaultAsync();
|
|
return fileInfo != null;
|
|
}
|
|
}
|