fix image generation when null
This commit is contained in:
parent
d9fe781343
commit
a2ee35d462
@ -3,31 +3,38 @@ using System.IO;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
public class NetworkShareAccess : IDisposable
|
public class NetworkShareAccess : IDisposable
|
||||||
{
|
{
|
||||||
private readonly string _networkPath;
|
private readonly string _networkPath;
|
||||||
private readonly string _username;
|
private readonly string _username;
|
||||||
private readonly string _password;
|
private readonly string _password;
|
||||||
|
|
||||||
private bool _isConnected = false;
|
private bool _isConnected = false;
|
||||||
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
public NetworkShareAccess(string networkPath, string username, string password)
|
public NetworkShareAccess(string networkPath, string username, string password)
|
||||||
{
|
{
|
||||||
// Validate and normalize the network path
|
|
||||||
_networkPath = networkPath?.Trim().Replace('/', '\\') ?? throw new ArgumentNullException(nameof(networkPath));
|
_networkPath = networkPath?.Trim().Replace('/', '\\') ?? throw new ArgumentNullException(nameof(networkPath));
|
||||||
if (!_networkPath.StartsWith(@"\\"))
|
if (!_networkPath.StartsWith(@"\\"))
|
||||||
{
|
|
||||||
throw new ArgumentException("Network path must start with \\\\");
|
throw new ArgumentException("Network path must start with \\\\");
|
||||||
}
|
|
||||||
|
|
||||||
_username = username ?? throw new ArgumentNullException(nameof(username));
|
_username = username ?? throw new ArgumentNullException(nameof(username));
|
||||||
_password = password ?? throw new ArgumentNullException(nameof(password));
|
_password = password ?? throw new ArgumentNullException(nameof(password));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectToNetworkPath()
|
public void ConnectToNetworkPath()
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
if (_isConnected) return;
|
if (_isConnected) return;
|
||||||
|
|
||||||
|
int retries = 0;
|
||||||
|
while (retries < 3)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
var netResource = new NetResource
|
var netResource = new NetResource
|
||||||
{
|
{
|
||||||
Scope = ResourceScope.GlobalNetwork,
|
Scope = ResourceScope.GlobalNetwork,
|
||||||
@ -38,18 +45,35 @@ public class NetworkShareAccess : IDisposable
|
|||||||
|
|
||||||
int result = WNetAddConnection2(netResource, _password, _username, 0);
|
int result = WNetAddConnection2(netResource, _password, _username, 0);
|
||||||
|
|
||||||
if (result != 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
string errorMessage = GetNetworkErrorDescription(result);
|
_isConnected = true;
|
||||||
Console.WriteLine($"Failed to connect to {_networkPath}. Error {result}: {errorMessage}");
|
Console.WriteLine($"Connected to {_networkPath}");
|
||||||
throw new IOException($"Failed to connect to network path. Error {result}: {errorMessage}");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isConnected = true;
|
if (result == 1219) // Multiple connections
|
||||||
Console.WriteLine($"Successfully connected to {_networkPath}");
|
{
|
||||||
|
WNetCancelConnection2(_networkPath, 0, true);
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
retries++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IOException($"Failed to connect. Error {result}: {GetNetworkErrorDescription(result)}");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (++retries >= 3) throw;
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisconnectFromNetworkShare()
|
public void DisconnectFromNetworkShare()
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
if (!_isConnected) return;
|
if (!_isConnected) return;
|
||||||
|
|
||||||
@ -57,36 +81,18 @@ public class NetworkShareAccess : IDisposable
|
|||||||
{
|
{
|
||||||
int result = WNetCancelConnection2(_networkPath, 0, true);
|
int result = WNetCancelConnection2(_networkPath, 0, true);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
Console.WriteLine($"Warning: Disconnect failed (Error {result})");
|
||||||
string errorMessage = GetNetworkErrorDescription(result);
|
|
||||||
Console.WriteLine($"Failed to disconnect from {_networkPath}. Error {result}: {errorMessage}");
|
|
||||||
throw new IOException($"Failed to disconnect from network path. Error {result}: {errorMessage}");
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($"Successfully disconnected from {_networkPath}");
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_isConnected = false;
|
_isConnected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DisconnectFromNetworkShare();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error during disposal: {ex.Message}");
|
|
||||||
// Suppress disposal errors
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetNetworkErrorDescription(int errorCode)
|
public void Dispose() => DisconnectFromNetworkShare();
|
||||||
{
|
|
||||||
return errorCode switch
|
private string GetNetworkErrorDescription(int errorCode) => errorCode switch
|
||||||
{
|
{
|
||||||
5 => "Access denied",
|
5 => "Access denied",
|
||||||
53 => "Network path not found",
|
53 => "Network path not found",
|
||||||
@ -96,7 +102,6 @@ public class NetworkShareAccess : IDisposable
|
|||||||
1219 => "Multiple connections to a server or shared resource not allowed",
|
1219 => "Multiple connections to a server or shared resource not allowed",
|
||||||
_ => new Win32Exception(errorCode).Message
|
_ => new Win32Exception(errorCode).Message
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
|
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
|
||||||
private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);
|
private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);
|
||||||
@ -104,9 +109,6 @@ public class NetworkShareAccess : IDisposable
|
|||||||
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
|
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
|
||||||
private static extern int WNetCancelConnection2(string name, int flags, bool force);
|
private static extern int WNetCancelConnection2(string name, int flags, bool force);
|
||||||
|
|
||||||
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern int WNetGetConnection(string localName, StringBuilder remoteName, ref int length);
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||||
private class NetResource
|
private class NetResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -49,18 +49,18 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
|
|
||||||
private Image? LoadImage(string? imagePath)
|
private Image? LoadImage(string? imagePath)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(imagePath))
|
if (string.IsNullOrEmpty(imagePath)) //check if photo is missing
|
||||||
{
|
{
|
||||||
return null;
|
return null; // returns 'nothing' (safe)
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Image.FromFile(imagePath);
|
return Image.FromFile(imagePath); //load photo
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return null;
|
return null; //if loading fails, returns 'nothing' (safe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
{
|
{
|
||||||
text.Span(_classifyID == "SD" ? "☑ Sand " : "☐ Sand ").Style(TextStyle.Default.FontSize(10));
|
text.Span(_classifyID == "SD" ? "☑ Sand " : "☐ Sand ").Style(TextStyle.Default.FontSize(10));
|
||||||
text.Span(_classifyID == "NS" ? " ☑ Non-sandy " : " ☐ Non-sandy ").Style(TextStyle.Default.FontSize(10));
|
text.Span(_classifyID == "NS" ? " ☑ Non-sandy " : " ☐ Non-sandy ").Style(TextStyle.Default.FontSize(10));
|
||||||
text.Span(_classifyID == "CO" ? "☑ Coquina" : "☐ Coquina").Style(TextStyle.Default.FontSize(10));
|
text.Span(_classifyID == "CQ" ? "☑ Coquina" : "☐ Coquina").Style(TextStyle.Default.FontSize(10));
|
||||||
});
|
});
|
||||||
|
|
||||||
column.Item()
|
column.Item()
|
||||||
@ -237,7 +237,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
|
|
||||||
// Row 1: Photos ====================================
|
// Row 1: Photos ====================================
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
table.Cell().Element(CellStyle).Height(150)
|
||||||
.Image(LoadImage(_photoPath1) ?? null) // Just pass null if no image
|
.Image(LoadImage(_photoPath1) ?? null) // Loads image or uses null. if exist, fill cell. if null, cell stay empty
|
||||||
.FitArea();
|
.FitArea();
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
table.Cell().Element(CellStyle).Height(150)
|
||||||
@ -288,28 +288,44 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
columns.RelativeColumn(1);
|
columns.RelativeColumn(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
// Helper function to safely add image cells
|
||||||
.Image(LoadImage(_photoPath5) ?? null) // Just pass null if no image
|
void AddOptionalImageCell(string imagePath)
|
||||||
.FitArea();
|
{
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
table.Cell().Element(CellStyle).Height(150).Element(cell =>
|
||||||
.Image(LoadImage(_photoPath6) ?? null) // Just pass null if no image
|
{
|
||||||
.FitArea();
|
var image = LoadImage(imagePath);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
cell.Image(image).FitArea();
|
||||||
|
}
|
||||||
|
// If null, leaves an empty cell
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Text($"Figure 5: {_optionalName1}")
|
// Row 1: Optional images 5 & 6
|
||||||
.FontSize(12).AlignLeft();
|
AddOptionalImageCell(_photoPath5);
|
||||||
table.Cell().Element(CellStyle).Text($"Figure 6: {_optionalName2}")
|
AddOptionalImageCell(_photoPath6);
|
||||||
|
|
||||||
|
// Row 2: Captions
|
||||||
|
table.Cell().Element(CellStyle)
|
||||||
|
.Text(string.IsNullOrEmpty(_photoPath5) ? "" : $"Figure 5: {_optionalName1}")
|
||||||
.FontSize(12).AlignLeft();
|
.FontSize(12).AlignLeft();
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
table.Cell().Element(CellStyle)
|
||||||
.Image(LoadImage(_photoPath7) ?? null) // Just pass null if no image
|
.Text(string.IsNullOrEmpty(_photoPath6) ? "" : $"Figure 6: {_optionalName2}")
|
||||||
.FitArea();
|
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
|
||||||
.Image(LoadImage(_photoPath8) ?? null) // Just pass null if no image
|
|
||||||
.FitArea();
|
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Text($"Figure 7: {_optionalName3}")
|
|
||||||
.FontSize(12).AlignLeft();
|
.FontSize(12).AlignLeft();
|
||||||
table.Cell().Element(CellStyle).Text($"Figure 8: {_optionalName4}")
|
|
||||||
|
// Row 3: Optional images 7 & 8
|
||||||
|
AddOptionalImageCell(_photoPath7);
|
||||||
|
AddOptionalImageCell(_photoPath8);
|
||||||
|
|
||||||
|
// Row 4: Captions
|
||||||
|
table.Cell().Element(CellStyle)
|
||||||
|
.Text(string.IsNullOrEmpty(_photoPath7) ? "" : $"Figure 7: {_optionalName3}")
|
||||||
|
.FontSize(12).AlignLeft();
|
||||||
|
|
||||||
|
table.Cell().Element(CellStyle)
|
||||||
|
.Text(string.IsNullOrEmpty(_photoPath8) ? "" : $"Figure 8: {_optionalName4}")
|
||||||
.FontSize(12).AlignLeft();
|
.FontSize(12).AlignLeft();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user