Compare commits
3 Commits
eee07fa409
...
4ec27709c9
Author | SHA1 | Date | |
---|---|---|---|
4ec27709c9 | |||
882dc50671 | |||
fc050631e7 |
@ -2,7 +2,6 @@
|
||||
{
|
||||
public class AddCommentDto
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public Guid TicketId { get; set; } = Guid.Empty;
|
||||
public Guid AuthorId { get; set; }
|
||||
public string MessageText { get; set; } = string.Empty;
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
public class CreateTicketDto
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public Guid StatusId { get; set; }
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
public class ForumAttachmentDto
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public Guid TicketId { get; set; } = Guid.Empty;
|
||||
public Guid? CommentId { get; set; }
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
|
14
Marco.Pms.Model/Dtos/Forum/UpdateAttachmentDto.cs
Normal file
14
Marco.Pms.Model/Dtos/Forum/UpdateAttachmentDto.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Marco.Pms.Model.Dtos.Forum
|
||||
{
|
||||
public class UpdateAttachmentDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid TicketId { get; set; } = Guid.Empty;
|
||||
public Guid? CommentId { get; set; }
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
public string? Base64Data { get; set; }
|
||||
public int FileSize { get; set; }
|
||||
public string ContentType { get; set; } = string.Empty;
|
||||
public DateTime SentAt { get; set; }
|
||||
}
|
||||
}
|
@ -8,6 +8,6 @@
|
||||
public string MessageText { get; set; } = string.Empty;
|
||||
public DateTime SentAt { get; set; }
|
||||
public Guid? ParentMessageId { get; set; } // For threaded replies
|
||||
public ICollection<ForumAttachmentDto>? Attachments { get; set; }
|
||||
public ICollection<UpdateAttachmentDto>? Attachments { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public int LinkedProjectId { get; set; }
|
||||
public int? LinkedActivityId { get; set; } // task or project ID
|
||||
public ICollection<ForumAttachmentDto>? Attachments { get; set; }
|
||||
public ICollection<UpdateAttachmentDto>? Attachments { get; set; }
|
||||
public Guid PriorityId { get; set; }
|
||||
public ICollection<Guid>? TagIds { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
|
@ -77,6 +77,16 @@ namespace Marco.Pms.Model.Mapper
|
||||
FileId = fileId,
|
||||
};
|
||||
}
|
||||
public static TicketAttachment ToTicketAttachmentFromUpdateAttachmentDto(this UpdateAttachmentDto AttachmentDto, Guid ticketId, Guid fileId, Guid? commentId = null)
|
||||
{
|
||||
return new TicketAttachment
|
||||
{
|
||||
TicketId = ticketId,
|
||||
CommentId = commentId,
|
||||
FileName = AttachmentDto.FileName,
|
||||
FileId = fileId,
|
||||
};
|
||||
}
|
||||
|
||||
public static Document ToDocumentFromForumAttachmentDto(this ForumAttachmentDto AttachmentDto, string objectKey, string thumbS3Key, DateTime uploadedAt, int tenantId)
|
||||
{
|
||||
@ -92,6 +102,20 @@ namespace Marco.Pms.Model.Mapper
|
||||
TenantId = tenantId
|
||||
};
|
||||
}
|
||||
public static Document ToDocumentFromUpdateAttachmentDto(this UpdateAttachmentDto AttachmentDto, string objectKey, string thumbS3Key, DateTime uploadedAt, int tenantId)
|
||||
{
|
||||
return new Document
|
||||
{
|
||||
FileName = AttachmentDto.FileName,
|
||||
ContentType = AttachmentDto.ContentType,
|
||||
S3Key = objectKey,
|
||||
ThumbS3Key = thumbS3Key,
|
||||
Base64Data = AttachmentDto.Base64Data,
|
||||
FileSize = AttachmentDto.FileSize,
|
||||
UploadedAt = uploadedAt,
|
||||
TenantId = tenantId
|
||||
};
|
||||
}
|
||||
public static ForumTicketVM ToForumTicketVMFromTicketForum(this TicketForum ticket, Employee employee)
|
||||
{
|
||||
return new ForumTicketVM
|
||||
|
@ -57,7 +57,7 @@ namespace MarcoBMS.Services.Controllers
|
||||
foreach (var attendanceLog in lstAttendance)
|
||||
{
|
||||
string objectKey = attendanceLog.Document.S3Key;
|
||||
string preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
attendanceLogVMs.Add(attendanceLog.ToAttendanceLogVMFromAttendanceLog(preSignedUrl, preSignedUrl));
|
||||
}
|
||||
return Ok(ApiResponse<object>.SuccessResponse(attendanceLogVMs, System.String.Format("{0} Attendance records fetched successfully", lstAttendance.Count), 200));
|
||||
@ -509,33 +509,16 @@ namespace MarcoBMS.Services.Controllers
|
||||
|
||||
if (Image != null && Image.ContentType != null)
|
||||
{
|
||||
byte[] fileBytes;
|
||||
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
|
||||
string fileName = _s3Service.GenerateFileName(Image.ContentType, TenantId, "Attendance");
|
||||
objectKey = await _s3Service.UploadFileAsync(stream, fileName, Image.ContentType);
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, TenantId, "attendance");
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
|
||||
document = new Document
|
||||
{
|
||||
FileName = Image.FileName ?? fileName,
|
||||
FileName = Image.FileName ?? "",
|
||||
ContentType = Image.ContentType,
|
||||
S3Key = objectKey,
|
||||
Base64Data = Image.Base64Data,
|
||||
|
@ -62,34 +62,14 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
foreach (var attachmentDto in createTicketDto.Attachments)
|
||||
{
|
||||
byte[] fileBytes;
|
||||
var Image = attachmentDto;
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
{
|
||||
_logger.LogError("Base64 data is missing");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
}
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error}", ex.Message);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
|
||||
|
||||
string fileName = _s3Service.GenerateFileName(Image.ContentType, tenantId, string.Empty);
|
||||
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, fileName, Image.ContentType);
|
||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
||||
|
||||
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, createTicketDto.CreatedAt, tenantId);
|
||||
_context.Documents.Add(document);
|
||||
@ -139,7 +119,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl));
|
||||
}
|
||||
@ -198,40 +178,20 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
if (!existingattachmentids.Contains(attachmentDto.Id) && attachmentDto.TicketId != updateTicketDto.Id)
|
||||
{
|
||||
byte[] fileBytes;
|
||||
var Image = attachmentDto;
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
{
|
||||
_logger.LogError("Base64 data is missing");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
}
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error}", ex.Message);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
||||
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
|
||||
|
||||
string fileName = _s3Service.GenerateFileName(Image.ContentType, tenantId, string.Empty);
|
||||
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, fileName, Image.ContentType);
|
||||
|
||||
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, updateTicketDto.CreatedAt, tenantId);
|
||||
Document document = attachmentDto.ToDocumentFromUpdateAttachmentDto(objectKey, objectKey, updateTicketDto.CreatedAt, tenantId);
|
||||
_context.Documents.Add(document);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var attachment = attachmentDto.ToTicketAttachmentFromForumAttachmentDto(ticketForum.Id, document.Id);
|
||||
var attachment = attachmentDto.ToTicketAttachmentFromUpdateAttachmentDto(ticketForum.Id, document.Id);
|
||||
attachments.Add(attachment);
|
||||
}
|
||||
}
|
||||
@ -313,7 +273,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
if (attachment.CommentId == null)
|
||||
{
|
||||
@ -376,33 +336,14 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
foreach (var attachmentDto in addCommentDto.Attachments)
|
||||
{
|
||||
byte[] fileBytes;
|
||||
var Image = attachmentDto;
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
{
|
||||
_logger.LogError("Base64 data is missing");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
}
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error}", ex.Message);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
|
||||
|
||||
string fileName = _s3Service.GenerateFileName(Image.ContentType, tenantId, string.Empty);
|
||||
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, fileName, Image.ContentType);
|
||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
||||
|
||||
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, addCommentDto.SentAt, tenantId);
|
||||
_context.Documents.Add(document);
|
||||
@ -428,7 +369,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl));
|
||||
}
|
||||
@ -461,46 +402,31 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
List<TicketAttachment> existingAttachments = await _context.TicketAttachments.Where(a => a.CommentId == updateComment.Id).ToListAsync();
|
||||
var existingattachmentids = existingAttachments.Select(a => a.Id).ToList();
|
||||
var attachmentDtoids = updateCommentDto.Attachments.Select(a => a.Id).ToList();
|
||||
|
||||
foreach (var attachmentDto in updateCommentDto.Attachments)
|
||||
List<Guid> attachmentDtoids = new List<Guid>();
|
||||
if (updateCommentDto.Attachments != null)
|
||||
{
|
||||
if (!existingattachmentids.Contains(attachmentDto.Id) && attachmentDto.CommentId != updateComment.Id)
|
||||
attachmentDtoids = updateCommentDto.Attachments.Select(a => a.Id).ToList();
|
||||
|
||||
foreach (var attachmentDto in updateCommentDto.Attachments)
|
||||
{
|
||||
byte[] fileBytes;
|
||||
var Image = attachmentDto;
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
if (!existingattachmentids.Contains(attachmentDto.Id) && attachmentDto.CommentId != updateComment.Id)
|
||||
{
|
||||
_logger.LogError("Base64 data is missing");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
var Image = attachmentDto;
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
{
|
||||
_logger.LogError("Base64 data is missing");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
}
|
||||
|
||||
var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, tenantId, "forum");
|
||||
|
||||
Document document = attachmentDto.ToDocumentFromUpdateAttachmentDto(objectKey, objectKey, existingComment.SentAt, tenantId);
|
||||
_context.Documents.Add(document);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var attachment = attachmentDto.ToTicketAttachmentFromUpdateAttachmentDto(existingComment.TicketId, document.Id, updateComment.Id);
|
||||
attachments.Add(attachment);
|
||||
}
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error}", ex.Message);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
|
||||
|
||||
string fileName = _s3Service.GenerateFileName(Image.ContentType, tenantId, string.Empty);
|
||||
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, fileName, Image.ContentType);
|
||||
|
||||
Document document = attachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, existingComment.SentAt, tenantId);
|
||||
_context.Documents.Add(document);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var attachment = attachmentDto.ToTicketAttachmentFromForumAttachmentDto(existingComment.TicketId, document.Id, updateComment.Id);
|
||||
attachments.Add(attachment);
|
||||
}
|
||||
}
|
||||
if (attachments.Count != 0)
|
||||
@ -537,7 +463,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
attachmentVMs.Add(attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl));
|
||||
}
|
||||
@ -568,32 +494,13 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
foreach (var forumAttachmentDto in forumAttachmentDtos)
|
||||
{
|
||||
byte[] fileBytes;
|
||||
if (string.IsNullOrEmpty(forumAttachmentDto.Base64Data))
|
||||
{
|
||||
_logger.LogError("Base64 data is missing");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Base64 data is missing", "Base64 data is missing", 400));
|
||||
}
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = forumAttachmentDto.Base64Data.Contains(",")
|
||||
? forumAttachmentDto.Base64Data.Substring(forumAttachmentDto.Base64Data.IndexOf(",") + 1)
|
||||
: forumAttachmentDto.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error}", ex.Message);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse(ex.Message, ex, 400)); ;
|
||||
}
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
|
||||
|
||||
string fileName = _s3Service.GenerateFileName(forumAttachmentDto.ContentType, tenantId, string.Empty);
|
||||
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, fileName, forumAttachmentDto.ContentType);
|
||||
var objectKey = await _s3Service.UploadFileAsync(forumAttachmentDto.Base64Data, tenantId, "forum");
|
||||
|
||||
Document document = forumAttachmentDto.ToDocumentFromForumAttachmentDto(objectKey, objectKey, forumAttachmentDto.SentAt, tenantId);
|
||||
_context.Documents.Add(document);
|
||||
@ -603,7 +510,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
_context.TicketAttachments.Add(attachment);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
string preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
string preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
|
||||
TicketAttachmentVM attachmentVM = attachment.ToTicketAttachmentVMFromTicketAttachment(preSignedUrl, preSignedUrl);
|
||||
ticketAttachmentVMs.Add(attachmentVM);
|
||||
@ -668,7 +575,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
if (attachment.CommentId == null)
|
||||
{
|
||||
@ -743,7 +650,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
if (attachment.CommentId == null)
|
||||
{
|
||||
@ -842,7 +749,7 @@ namespace Marco.Pms.Services.Controllers
|
||||
string preSignedUrl = string.Empty;
|
||||
if (document != null)
|
||||
{
|
||||
preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(document.S3Key);
|
||||
}
|
||||
if (attachment.CommentId == null)
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using Marco.Pms.Services.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
@ -33,41 +32,22 @@ namespace MarcoBMS.Services.Controllers
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
[HttpPost("upload-image")]
|
||||
public async Task<IActionResult> SendToSThree([FromBody] FileUploadModel Image)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
return BadRequest("Base64 data is missing");
|
||||
//[HttpPost("upload-image")]
|
||||
//public async Task<IActionResult> SendToSThree([FromBody] FileUploadModel Image)
|
||||
//{
|
||||
// if (string.IsNullOrEmpty(Image.Base64Data))
|
||||
// return BadRequest("Base64 data is missing");
|
||||
// var objectKey = await _s3Service.UploadFileAsync(Image.Base64Data, 1, "Forum");
|
||||
// //var objectKey = await _s3Service.UploadFileAsync(Image.FileName, Image.ContentType);
|
||||
// var preSignedUrl = _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
|
||||
byte[] fileBytes;
|
||||
// return Ok(new
|
||||
// {
|
||||
// objectKey,
|
||||
// url = preSignedUrl
|
||||
// });
|
||||
|
||||
try
|
||||
{
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = Image.Base64Data.Contains(",")
|
||||
? Image.Base64Data.Substring(Image.Base64Data.IndexOf(",") + 1)
|
||||
: Image.Base64Data;
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
//return BadRequest("Invalid base64 string.");
|
||||
return BadRequest(error);
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream(fileBytes);
|
||||
var objectKey = await _s3Service.UploadFileAsync(stream, Image.FileName, Image.ContentType);
|
||||
//var objectKey = await _s3Service.UploadFileAsync(Image.FileName, Image.ContentType);
|
||||
var preSignedUrl = await _s3Service.GeneratePreSignedUrlAsync(objectKey);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
objectKey,
|
||||
url = preSignedUrl
|
||||
});
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
@ -28,6 +28,8 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
|
||||
<PackageReference Include="Mime-Detective" Version="24.12.2" />
|
||||
<PackageReference Include="Mime-Detective.Definitions.Exhaustive" Version="24.12.2" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
|
||||
|
@ -4,6 +4,7 @@ using Amazon.S3.Transfer;
|
||||
using Marco.Pms.Model.Utilities;
|
||||
using MarcoBMS.Services.Service;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeDetective;
|
||||
|
||||
namespace Marco.Pms.Services.Service
|
||||
{
|
||||
@ -13,10 +14,12 @@ namespace Marco.Pms.Services.Service
|
||||
private readonly IAmazonS3 _s3Client;
|
||||
private readonly string _bucketName = "your-bucket-name";
|
||||
private readonly ILoggingService _logger;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public S3UploadService(IOptions<AWSSettings> awsOptions, ILoggingService logger)
|
||||
public S3UploadService(IOptions<AWSSettings> awsOptions, ILoggingService logger, IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
var settings = awsOptions.Value;
|
||||
|
||||
var region = Amazon.RegionEndpoint.GetBySystemName(settings.Region);
|
||||
@ -25,35 +28,57 @@ namespace Marco.Pms.Services.Service
|
||||
_s3Client = new AmazonS3Client(settings.AccessKey, settings.SecretKey, region);
|
||||
}
|
||||
//public async Task<string> UploadFileAsync(string fileName, string contentType)
|
||||
public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType)
|
||||
public async Task<string> UploadFileAsync(string base64Data, int tenantId, string tag)
|
||||
{
|
||||
// Generate a unique object key (you can customize this)
|
||||
var objectKey = $"{fileName}";
|
||||
byte[] fileBytes;
|
||||
|
||||
var uploadRequest = new TransferUtilityUploadRequest
|
||||
//If base64 has a data URI prefix, strip it
|
||||
var base64 = base64Data.Contains(",")
|
||||
? base64Data.Substring(base64Data.IndexOf(",") + 1)
|
||||
: base64Data;
|
||||
var allowedFilesType = _configuration.GetSection("WhiteList:ContentType")
|
||||
.GetChildren()
|
||||
.Select(x => x.Value)
|
||||
.ToList();
|
||||
string fileType = GetContentTypeFromBase64(base64);
|
||||
if (allowedFilesType != null && allowedFilesType.Contains(fileType))
|
||||
{
|
||||
InputStream = fileStream,
|
||||
Key = objectKey,
|
||||
BucketName = _bucketName,
|
||||
ContentType = contentType,
|
||||
AutoCloseStream = true
|
||||
};
|
||||
try
|
||||
{
|
||||
var transferUtility = new TransferUtility(_s3Client);
|
||||
await transferUtility.UploadAsync(uploadRequest);
|
||||
_logger.LogInfo("File uploaded to Amazon S3");
|
||||
return objectKey;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error} while uploading file to S3", ex.Message);
|
||||
return string.Empty;
|
||||
string fileName = GenerateFileName(fileType, tenantId, tag);
|
||||
|
||||
fileBytes = Convert.FromBase64String(base64);
|
||||
|
||||
|
||||
using var fileStream = new MemoryStream(fileBytes);
|
||||
|
||||
// Generate a unique object key (you can customize this)
|
||||
var objectKey = $"{fileName}";
|
||||
|
||||
var uploadRequest = new TransferUtilityUploadRequest
|
||||
{
|
||||
InputStream = fileStream,
|
||||
Key = objectKey,
|
||||
BucketName = _bucketName,
|
||||
ContentType = fileType,
|
||||
AutoCloseStream = true
|
||||
};
|
||||
try
|
||||
{
|
||||
var transferUtility = new TransferUtility(_s3Client);
|
||||
await transferUtility.UploadAsync(uploadRequest);
|
||||
_logger.LogInfo("File uploaded to Amazon S3");
|
||||
return objectKey;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{error} while uploading file to S3", ex.Message);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException("Unsupported file type.");
|
||||
}
|
||||
public async Task<string> GeneratePreSignedUrlAsync(string objectKey)
|
||||
public string GeneratePreSignedUrlAsync(string objectKey)
|
||||
{
|
||||
int expiresInMinutes = 1;
|
||||
int expiresInMinutes = 10;
|
||||
var request = new GetPreSignedUrlRequest
|
||||
{
|
||||
BucketName = _bucketName,
|
||||
@ -95,11 +120,116 @@ namespace Marco.Pms.Services.Service
|
||||
}
|
||||
public string GenerateFileName(string contentType, int tenantId, string? name)
|
||||
{
|
||||
string extenstion = contentType.Split("/")[1];
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return $"{tenantId}_{DateTime.UtcNow:yyyyMMddHHmmssfff}.{extenstion}";
|
||||
return $"{name}_{tenantId}_{DateTime.UtcNow:yyyyMMddHHmmssfff}.{extenstion}";
|
||||
string extenstion = GetExtensionFromMimeType(contentType);
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return $"{tenantId}_{DateTime.UtcNow:yyyyMMddHHmmssfff}{extenstion}";
|
||||
return $"{name}_{tenantId}_{DateTime.UtcNow:yyyyMMddHHmmssfff}{extenstion}";
|
||||
|
||||
}
|
||||
public string GetExtensionFromMimeType(string contentType)
|
||||
{
|
||||
switch (contentType.ToLowerInvariant())
|
||||
{
|
||||
case "application/pdf":
|
||||
return ".pdf";
|
||||
|
||||
case "application/msword":
|
||||
return ".doc";
|
||||
|
||||
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
||||
return ".docx";
|
||||
|
||||
case "application/vnd.ms-excel":
|
||||
return ".xls";
|
||||
|
||||
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
||||
return ".xlsx";
|
||||
|
||||
case "application/mspowerpoint":
|
||||
return ".ppt";
|
||||
|
||||
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
||||
return ".pptx";
|
||||
|
||||
case "text/plain":
|
||||
return ".txt";
|
||||
|
||||
case "application/rtf":
|
||||
return ".rtf";
|
||||
|
||||
case "image/jpeg":
|
||||
return ".jpg";
|
||||
|
||||
case "image/png":
|
||||
return ".png";
|
||||
|
||||
case "image/gif":
|
||||
return ".gif";
|
||||
|
||||
case "image/bmp":
|
||||
return ".bmp";
|
||||
|
||||
case "text/csv":
|
||||
return ".csv";
|
||||
|
||||
default:
|
||||
return ""; // or ".bin", or throw an error, based on your needs
|
||||
}
|
||||
}
|
||||
public string GetContentTypeFromBase64(string base64String)
|
||||
{
|
||||
if (string.IsNullOrEmpty(base64String))
|
||||
{
|
||||
return string.Empty; // Or handle the empty case as needed
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 1. Decode the Base64 string to a byte array
|
||||
byte[] decodedBytes = Convert.FromBase64String(base64String);
|
||||
|
||||
// 2. Create a ContentInspector (using default definitions for this example)
|
||||
var inspector = new ContentInspectorBuilder()
|
||||
{
|
||||
Definitions = MimeDetective.Definitions.DefaultDefinitions.All()
|
||||
}.Build();
|
||||
|
||||
// 3. Inspect the byte array to determine the content type
|
||||
var results = inspector.Inspect(decodedBytes);
|
||||
|
||||
if (results.Any())
|
||||
{
|
||||
var bestMatch = results
|
||||
.OrderByDescending(r => r.Points)
|
||||
.FirstOrDefault();
|
||||
if (bestMatch?.Definition?.File?.MimeType != null)
|
||||
{
|
||||
return bestMatch.Definition.File.MimeType;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Warning: Could not find MimeType, Type, or ContentType property in Definition.");
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "application/octet-stream"; // Default if type cannot be determined
|
||||
}
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
// Handle cases where the input string is not valid Base64
|
||||
Console.WriteLine("Error: Invalid Base64 string.");
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Handle other potential errors during decoding or inspection
|
||||
Console.WriteLine($"An error occurred: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -86,6 +86,24 @@
|
||||
"SecretKey": "NTS5XXgZINQbU6ctpNuLXtIY/Qk9GCgD9Rr5yNJP",
|
||||
"Region": "us-east-1",
|
||||
"BucketName": "testenv-marco-pms-documents"
|
||||
},
|
||||
"WhiteList": {
|
||||
"ContentType": [
|
||||
"application/pdf", // pdf
|
||||
"application/msword", // Doc
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", //docx
|
||||
"application/vnd.ms-excel", //xls
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", //xlsx
|
||||
"application/mspowerpoint", //ppt
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation", //pptx
|
||||
"text/plain", //txt
|
||||
"application/rtf", //rtf
|
||||
"text/csv", //csv
|
||||
"image/jpg", //jpg
|
||||
"image/jpeg", //jpeg
|
||||
"image/png", //png
|
||||
"image/gif", //gif
|
||||
"image/bmp" //bmp
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user