using BMA.EHR.Recruit.Service.Core; using BMA.EHR.Recruit.Service.Data; using Microsoft.EntityFrameworkCore; using MongoDB.Driver.GridFS; using MongoDB.Driver; using BMA.EHR.Recruit.Service.Models.Documents; using System.Net.Http.Headers; using BMA.EHR.Recruit.Service.Responses.Document; using MongoDB.Bson; namespace BMA.EHR.Recruit.Service.Services { public class DocumentService { private readonly ApplicationDbContext _context; private readonly IConfiguration _configuration; private readonly IWebHostEnvironment _webHostEnvironment; private const string MONGO_DATABASE = "bma-recruit"; public DocumentService(ApplicationDbContext context, IConfiguration configuration, IWebHostEnvironment webHostEnvironment) { _context = context; _configuration = configuration; _webHostEnvironment = webHostEnvironment; } public string MongoConnectionString { get => _configuration.GetConnectionString("MongoConnection"); } public async Task UploadFile(IFormFile file, string newFileName = "") { var fileName = ""; var fileExt = Path.GetExtension(file.FileName); if (newFileName != "") fileName = $"{newFileName}"; else fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); if (!Directory.Exists(tmpDir)) Directory.CreateDirectory(tmpDir); var tmpFile = Path.Combine(tmpDir, $"tmp_{DateTime.Now.ToString("ddMMyyyyHHmmss")}{fileExt}"); try { // upload to tmp using (var stream = new FileStream(tmpFile, FileMode.Create)) { file.CopyTo(stream); } var mongo = new MongoClient(MongoConnectionString); var bucket = new GridFSBucket(mongo.GetDatabase(MONGO_DATABASE)); using (var fs = new FileStream(tmpFile, FileMode.Open, FileAccess.Read)) { var fileId = bucket.UploadFromStream(fileName, fs); var info = new FileInfo(tmpFile); try { var doc = new Document() { FileName = fileName, FileType = file.ContentType, FileSize = Convert.ToInt32(file.Length), ObjectRefId = fileId.ToString(), CreatedDate = DateTime.Now }; await _context.Documents.AddAsync(doc); await _context.SaveChangesAsync(); return doc; } catch { bucket.Delete(fileId); throw new Exception(GlobalMessages.CannotInsertToDatabase); } } } catch { throw; } finally { System.IO.File.Delete(tmpFile); } } public async Task DeleteFile(Guid fileId) { try { var doc = await _context.Documents.AsQueryable() .FirstOrDefaultAsync(x => x.Id == fileId); if (doc == null) throw new Exception(GlobalMessages.FileNotFoundOnServer); var mongo = new MongoClient(MongoConnectionString); var bucket = new GridFSBucket(mongo.GetDatabase(MONGO_DATABASE)); bucket.Delete(ObjectId.Parse(doc.ObjectRefId)); _context.Documents.Remove(doc); await _context.SaveChangesAsync(); } catch { throw; } } public async Task DownloadFile(Guid fileId) { var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); if (!Directory.Exists(tmpDir)) Directory.CreateDirectory(tmpDir); var tmpFile = Path.Combine(tmpDir, $"tmp_{DateTime.Now.ToString("ddMMyyyyHHmmss")}"); try { var doc = await _context.Documents.AsQueryable() .FirstOrDefaultAsync(x => x.Id == fileId); if (doc == null) throw new Exception(GlobalMessages.FileNotFoundOnServer); var fileExt = Path.GetExtension(doc.FileName); tmpFile = tmpFile + fileExt; var mongo = new MongoClient(MongoConnectionString); var bucket = new GridFSBucket(mongo.GetDatabase(MONGO_DATABASE)); var f = bucket.DownloadAsBytes(ObjectId.Parse(doc.ObjectRefId)); return new FileDownloadResponse { FileName = doc.FileName, FileType = doc.FileType, FileContent = f }; } catch { throw; } finally { File.Delete(tmpFile); } } } }