Files
BeWoPlaner/Data/Access/LocalTenantFileStorageDAO.cs
2025-06-13 15:04:47 +02:00

130 lines
3.8 KiB
C#

using BeWo.Data.Entities;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.Exceptions;
using BS.Shared.Interface;
using DevExpress.DataAccess.Native.Web;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using Task = System.Threading.Tasks.Task;
namespace BeWo.Data.Access
{
public class LocalTenantFileStorageDAO
{
public string Tenant => MultitenancyOperationContextExt.Current?.Tenant ?? throw new BeWoInvalidOperationException(AppError.MultitenancyOperationTenantUnknown);
private readonly string _rootPath;
public LocalTenantFileStorageDAO(string rootPath)
{
_rootPath = rootPath;
}
public string GetXRechnungFileName(long invoicebase_oid)
{
return $"invoicebase_{invoicebase_oid}_xrechnung.pdf";
}
private string GetFilePath(string filePath)
{
return Path.Combine(_rootPath, Tenant, filePath);
}
public StoredFile SaveHybridFile(BWPFeature feature, string pFileName, string pContentType, Stream content,
TableID? pBeWoObjectTid = null, long? pBeWoObjectOid = null, CancellationToken cancellationToken = default)
{
// Prüfe Namen
if (SecurityUtils.ContainsInvalidFilenameChars(pFileName))
throw new BeWoInvalidOperationException(AppError.FileNameInvalidChar);
var lFilePath = Path.Combine(feature.ToString(), pFileName);
// Prüfe Path
if (Path.GetFileName(lFilePath) != pFileName)
throw new BeWoInvalidOperationException(AppError.FileNameNotEqFilePath);
// Prüfe Doppelte Belegung
if (DAOFactory.GenericDAO.Exists<StoredFile>(nameof(StoredFile.FilePath), lFilePath))
throw new BeWoInvalidOperationException(AppError.StoredFileAlreadyExists);
// Erstelle DB Eintrag
var storedfile = new StoredFile();
storedfile.FileName = pFileName;
storedfile.FilePath = lFilePath;
storedfile.ContentType = pContentType;
storedfile.BeWoObjectTid = (int?)pBeWoObjectTid;
storedfile.BeWoObjectOid = pBeWoObjectOid;
// Speichere FileAsync
storedfile = SaveFileAsync(storedfile, content, cancellationToken).GetAwaiter().GetResult();
// Speichere DB Eintrag
DAOFactory.GenericDAO.Insert(storedfile);
return storedfile;
}
private async Task<StoredFile> SaveFileAsync(StoredFile storedFile, Stream content, CancellationToken cancellationToken = default)
{
// Erstelle File Ordner
var path = GetFilePath(storedFile.FilePath);
var directory = Path.GetDirectoryName(path);
Directory.CreateDirectory(directory);
// Speichere Datei
using (var stream = File.Create(path))
{
await content.CopyToAsync(stream, bufferSize: 81920, cancellationToken).ConfigureAwait(true);
storedFile.Size = content.Position;
storedFile.Checksum = SecurityUtils.GetChecksumBuffered(content);
}
return storedFile;
}
public IStoredFile GetStoredFile(BWPFeature feature, string pFileName)
{
var lFilePath = Path.Combine(feature.ToString(), pFileName);
return GetFileInfo(lFilePath);
}
public IStoredFile GetFileInfo(string filePath)
{
var file = DAOFactory.GenericDAO.GetByProperty<StoredFile>(nameof(StoredFile.FilePath), filePath);
return file;
}
public Stream GetFileContent(IStoredFile storedFile, CancellationToken cancellationToken = default)
{
var path = GetFilePath(storedFile.FilePath);
if (!File.Exists(path))
return null;
Stream stream = File.OpenRead(path);
return stream;
}
public bool DeleteFile(IStoredFile storedFile, CancellationToken cancellationToken = default)
{
var path = GetFilePath(storedFile.FilePath);
if (File.Exists(path))
{
File.Delete(path);
return true;
}
return false;
}
}
}