diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs index 16c223c..b7cd328 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs @@ -136,6 +136,29 @@ namespace DamageAssesment.Api.Attachments.Controllers } } /// + /// download an existing attachment. + /// + [HttpGet("attachments/download/{id}")] + public async Task downloadfile1(int id) + { + try + { + var result = await this.AttachmentProvider.GetDownloadAttachmentAsync(id); + if(!result.IsSuccess) + return NotFound(); + byte[] fileContent = await UploadService.DownloadFile(result.Attachment.URI); + if (fileContent == null || fileContent.Length == 0) + return NotFound(); + var contentType = "application/octet-stream"; + return File(fileContent, contentType, result.Attachment.FileName); + } + catch (Exception ex) + { + // Handle the exception here or log it + return StatusCode(500, "An error occurred: " + ex.Message); + } + } + /// /// Delete an existing attachment. /// [HttpDelete("attachments/{id}")] diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs index 5e56dbb..06c4ead 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAttachmentsProvider.cs @@ -9,6 +9,7 @@ namespace DamageAssesment.Api.Attachments.Interfaces Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> PostAttachmentAsync(List Attachments); Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> PutAttachmentAsync(List Attachments); Task<(bool IsSuccess, Models.Attachment Attachment, string Path)> DeleteAttachmentAsync(int Id); + Task<(bool IsSuccess, Models.Attachment Attachment, string Path)> GetDownloadAttachmentAsync(int Id); Task<(bool IsSuccess, int counter, string Path)> DeleteAttachmentsAsync(int responseId, int answerId); Task<(bool IsSuccess, int counter, string Path)> DeleteBulkAttachmentsAsync(int responseId, List answerIds); Task<(bool IsSuccess, int counter, string message)> GetAttachmentCounter(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs index f645593..f89653f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IUploadService.cs @@ -7,6 +7,7 @@ namespace DamageAssesment.Api.Attachments.Interfaces List UploadAttachment(int responseId,int answerId, int counter, List postedFile); List UploadAttachment(int responseId, int counter, List answers); public List UpdateAttachments(int responseId, List answers, IEnumerable attachments); + Task DownloadFile(string path); void Deletefile(string path); void Movefile(string path); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs index 6aa5ed1..018740c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Program.cs @@ -27,6 +27,7 @@ builder.Services.AddSwaggerGen(c => var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); +builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs index 92c20e5..3489e28 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AttachmentsProvider.cs @@ -13,25 +13,33 @@ namespace DamageAssesment.Api.Attachments.Providers private AttachmentsDbContext AttachmentDbContext; private ILogger logger; private IUploadService uploadservice; - private IMapper mapper; - - public AttachmentsProvider(AttachmentsDbContext AttachmentDbContext, ILogger logger, IMapper mapper,IUploadService uploadservice) + private IMapper mapper; + private readonly IHttpContextAccessor httpContextAccessor; + private string baseUrl; + public AttachmentsProvider(AttachmentsDbContext AttachmentDbContext, ILogger logger, IMapper mapper,IUploadService uploadservice, IHttpContextAccessor httpContextAccessor) { this.AttachmentDbContext = AttachmentDbContext; this.logger = logger; this.mapper = mapper; this.uploadservice = uploadservice; - //SeedData(); + this.httpContextAccessor = httpContextAccessor; + baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; + baseUrl = baseUrl + "/attachments/download"; + SeedData(); } public async Task<(bool IsSuccess, IEnumerable Attachments, string ErrorMessage)> GetAttachmentsAsync() { - + try { logger?.LogInformation("Query Question"); var Attachment = await AttachmentDbContext.Attachments.AsNoTracking().Where(a => !a.IsDeleted).ToListAsync(); if (Attachment != null) { + foreach (var attachment in Attachment) + { + attachment.URI = $"{baseUrl}/{attachment.Id}"; + } logger?.LogInformation($"{Attachment.Count} Attachments(s) found"); var result = mapper.Map, IEnumerable>(Attachment); return (true, result, null); @@ -54,6 +62,7 @@ namespace DamageAssesment.Api.Attachments.Providers if (Attachment != null) { logger?.LogInformation($"{Attachment} customer(s) found"); + Attachment.URI = $"{baseUrl}/{Attachment.Id}"; var result = mapper.Map(Attachment); return (true, result, null); } @@ -73,6 +82,10 @@ namespace DamageAssesment.Api.Attachments.Providers List attachments = mapper.Map, List>(Attachments); AttachmentDbContext.Attachments.AddRange(attachments); await AttachmentDbContext.SaveChangesAsync(); + foreach (var attachment in attachments) + { + attachment.URI = $"{baseUrl}/{attachment.Id}"; + } var result = mapper.Map, IEnumerable>(attachments); return (true, result, null); } @@ -91,6 +104,10 @@ namespace DamageAssesment.Api.Attachments.Providers List attachments = mapper.Map, List>(Attachments); AttachmentDbContext.Attachments.UpdateRange(attachments); await AttachmentDbContext.SaveChangesAsync(); + foreach (var attachment in attachments) + { + attachment.URI = $"{baseUrl}/{attachment.Id}"; + } var result = mapper.Map, IEnumerable>(attachments); return (true, result, null); } @@ -197,6 +214,24 @@ namespace DamageAssesment.Api.Attachments.Providers { return AttachmentDbContext.Attachments.AsNoTracking().Count(e => e.Id == id && !e.IsDeleted) > 0; } + public async Task<(bool IsSuccess, Models.Attachment Attachment, string Path)> GetDownloadAttachmentAsync(int Id) + { + try + { + Db.Attachment Attachment = AttachmentDbContext.Attachments.Where(a => a.Id == Id).AsNoTracking().FirstOrDefault(); + if (Attachment == null) + { + return (false, null, "Not Found"); + } + return (true, mapper.Map(Attachment), $"Attachment {Id}"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } private void SeedData() { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs index 8c9045c..6e03fd0 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/UploadService.cs @@ -24,6 +24,23 @@ namespace DamageAssesment.Api.Attachments.Providers uploadpath = configuration.GetValue("Fileupload:folderpath"); Deletepath = configuration.GetValue("Fileupload:Deletepath"); } + public async Task DownloadFile(string path) + { + try + { + if (System.IO.File.Exists(path)) + { + return await System.IO.File.ReadAllBytesAsync(path); + } + + return null; // File not found + } + catch (Exception ex) + { + // Handle or log the exception as needed + throw; + } + } public List UploadAttachment(int responseId,int answerId,int counter, List postedFile) { var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), uploadpath); @@ -89,7 +106,7 @@ namespace DamageAssesment.Api.Attachments.Providers { counter++; - var UserfileName = Path.GetFileName(file.FileName); + var UserfileName = Path.GetFileName(file.FileName+ file.FileExtension); var fileName = String.Format("Attachment_{0}{1}", counter, file.FileExtension); var dbPath = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(dbPath, Convert.FromBase64String(file.FileContent)); @@ -126,7 +143,7 @@ namespace DamageAssesment.Api.Attachments.Providers foreach (var file in item.postedFiles) { Models.Attachment attachment= attachments.Where(a=>a.Id == file.AttachmentId).FirstOrDefault(); - var UserfileName = Path.GetFileName(file.FileName); + var UserfileName = Path.GetFileName(file.FileName + file.FileExtension); var fileName = String.Format("Attachment_{0}{1}", attachment?.Id, file.FileExtension); var dbPath = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(dbPath, Convert.FromBase64String(file.FileContent)); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs index 99d00a8..1d2e3de 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs @@ -104,6 +104,29 @@ namespace DamageAssesment.Api.DocuLinks.Controllers return NotFound(); } /// + /// download an existing attachment. + /// + [HttpGet("doculinks/download/{id}")] + public async Task downloadfile1(int id) + { + try + { + var result = await this.documentsProvider.GetDownloadAttachmentAsync(id); + if (!result.IsSuccess) + return NotFound(); + byte[] fileContent = await uploadService.DownloadFile(result.DoculinkAttachments.Path); + if (fileContent == null || fileContent.Length == 0) + return NotFound(); + var contentType = "application/octet-stream"; + return File(fileContent, contentType, result.DoculinkAttachments.docName); + } + catch (Exception ex) + { + // Handle the exception here or log it + return StatusCode(500, "An error occurred: " + ex.Message); + } + } + /// /// Get all Doculink. /// /// diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs index e9717ee..22f0fe6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs @@ -12,6 +12,7 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> PostDocumentAsync(Models.Doculink Document); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id, Models.Doculink Document); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> DeleteDocumentAsync(int id); + Task<(bool IsSuccess, Models.DoculinkAttachments DoculinkAttachments, string Path)> GetDownloadAttachmentAsync(int id); Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs index 4219fd6..4fbc5ee 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IUploadService.cs @@ -7,6 +7,7 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces Models.Doculink UploadDocument( int counter, ReqDoculink documentInfo); public Models.Doculink UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo); void Deletefile(string path); + Task DownloadFile(string path); void Movefile(string path); } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs index a2ec7ef..ec3acea 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Program.cs @@ -24,6 +24,7 @@ builder.Services.AddSwaggerGen(c => // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs index 749f200..30d3103 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs @@ -2,10 +2,12 @@ using DamageAssesment.Api.DocuLinks.Db; using DamageAssesment.Api.DocuLinks.Interfaces; using DamageAssesment.Api.DocuLinks.Models; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Internal; using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.Eventing.Reader; using System.Reflection.Metadata; @@ -23,13 +25,18 @@ namespace DamageAssesment.Api.DocuLinks.Providers private ILogger logger; private IUploadService uploadservice; private IMapper mapper; + private readonly IHttpContextAccessor httpContextAccessor; + private string baseUrl; - public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice) + public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice, IHttpContextAccessor httpContextAccessor) { this.DocumentDbContext = DocumentDbContext; this.logger = logger; this.mapper = mapper; this.uploadservice = uploadservice; + this.httpContextAccessor = httpContextAccessor; + baseUrl = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; + baseUrl = baseUrl + "/doculinks/download"; SeedData(); } @@ -173,15 +180,38 @@ namespace DamageAssesment.Api.DocuLinks.Providers } private List GetDocumentAttachment(int id,string? language) { + List doculinkAttachments = null; if (string.IsNullOrEmpty(language)) { - return mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); + doculinkAttachments = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList(); } else { - return mapper.Map, List>( - DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList()); + doculinkAttachments = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id && a.Language == language).ToList(); + } + foreach (var attachment in doculinkAttachments) + { + if (attachment.IsAttachments) + attachment.Path = $"{baseUrl}/{attachment.Id}"; + } + return mapper.Map, List>(doculinkAttachments); + } + public async Task<(bool IsSuccess, Models.DoculinkAttachments DoculinkAttachments, string Path)> GetDownloadAttachmentAsync(int id) + { + try + { + Db.DoculinkAttachments Attachment = DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.Id == id).AsNoTracking().FirstOrDefault(); + if (Attachment == null) + { + return (false, null, "Not Found"); + } + return (true, mapper.Map(Attachment), $"Attachment {id}"); + } + catch (Exception ex) + { + + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); } } public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive) @@ -358,7 +388,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(Document.linkTypeId, "")); result.titles = multilan.titles; result.description = multilan.description; - result.doclinksAttachments = Document.doclinksAttachments; + result.doclinksAttachments = GetDocumentAttachment(document.Id,""); return (true, result, null); } catch (Exception ex) @@ -400,7 +430,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(document.linkTypeId, "")); result.titles = multilan.titles; result.description = multilan.description; - result.doclinksAttachments = Document.doclinksAttachments; + result.doclinksAttachments = GetDocumentAttachment(document.Id, ""); return (true, result, "Successful"); } else @@ -438,7 +468,8 @@ namespace DamageAssesment.Api.DocuLinks.Providers result.titles = multilan.titles; result.description = multilan.description; result.linktypes = CreateMultiLanguageLinkTypeObject(GetLinkTypeTranslations(result.linkTypeId, "")); - result.doclinksAttachments = GetDocumentAttachment(id, ""); + result.doclinksAttachments = mapper.Map, List>( + DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == id).ToList()); Document.IsActive = false; DocumentDbContext.Documents.Update(Document); DocumentDbContext.SaveChanges(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs index b4c5b52..12e29c3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs @@ -25,6 +25,23 @@ namespace DamageAssesment.Api.DocuLinks.Providers uploadpath = configuration.GetValue("Fileupload:folderpath"); Deletepath = configuration.GetValue("Fileupload:Deletepath"); } + public async Task DownloadFile(string path) + { + try + { + if (System.IO.File.Exists(path)) + { + return await System.IO.File.ReadAllBytesAsync(path); + } + + return null; // File not found + } + catch (Exception ex) + { + // Handle or log the exception as needed + throw; + } + } public Models.Doculink UploadDocument(int counter, ReqDoculink documentInfo) { @@ -44,7 +61,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers counter++; if (item.IsAttachments) { - UserfileName = Path.GetFileName(item.FileName); + UserfileName = Path.GetFileName(item.FileName + item.FileExtension); var fileName = String.Format("Document_{0}{1}", counter, item.FileExtension); path = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent)); @@ -85,7 +102,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers counter++; if (item.IsAttachments) { - UserfileName = Path.GetFileName(item.FileName); + UserfileName = Path.GetFileName(item.FileName+item.FileExtension); var fileName = String.Format("Document_{0}{1}", counter, item.FileExtension); path = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent));