|
@@ -13,7 +13,7 @@ public static class TypeExtensions
|
|
|
return guid;
|
|
return guid;
|
|
|
|
|
|
|
|
if (property.PropertyType == typeof(Guid?)) return null;
|
|
if (property.PropertyType == typeof(Guid?)) return null;
|
|
|
- return Guid.Empty;
|
|
|
|
|
|
|
+ return Guid.Empty;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static object? HandleEnum(XLCellValue value, PropertyInfo property, Type? nullableUnderlyingType)
|
|
private static object? HandleEnum(XLCellValue value, PropertyInfo property, Type? nullableUnderlyingType)
|
|
@@ -23,11 +23,11 @@ public static class TypeExtensions
|
|
|
return Enum.TryParse(nullableUnderlyingType, value.GetText(), true, out var enumNullableValue)
|
|
return Enum.TryParse(nullableUnderlyingType, value.GetText(), true, out var enumNullableValue)
|
|
|
? enumNullableValue : null;
|
|
? enumNullableValue : null;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return Enum.TryParse(property.PropertyType, value.GetText(), true, out var enumValue)
|
|
return Enum.TryParse(property.PropertyType, value.GetText(), true, out var enumValue)
|
|
|
? enumValue : Enum.GetValues(property.PropertyType).GetValue(0);
|
|
? enumValue : Enum.GetValues(property.PropertyType).GetValue(0);
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private static object? GetAdditionalTypeFromText(XLCellValue value, PropertyInfo? property = null)
|
|
private static object? GetAdditionalTypeFromText(XLCellValue value, PropertyInfo? property = null)
|
|
|
{
|
|
{
|
|
|
if (property == null) return value.GetText();
|
|
if (property == null) return value.GetText();
|
|
@@ -38,15 +38,17 @@ public static class TypeExtensions
|
|
|
case var _ when pt == typeof(Guid) || pt == typeof(Guid?):
|
|
case var _ when pt == typeof(Guid) || pt == typeof(Guid?):
|
|
|
return HandleGuid(value, property);
|
|
return HandleGuid(value, property);
|
|
|
case var _ when pt == typeof(DateTime) || pt == typeof(DateTime?):
|
|
case var _ when pt == typeof(DateTime) || pt == typeof(DateTime?):
|
|
|
- return DateTime.TryParse(value.GetText(), out var dateValue) ? dateValue : default;
|
|
|
|
|
|
|
+ DateTime.TryParse(value.GetText(), out var dateValue);
|
|
|
|
|
+ return dateValue;
|
|
|
case var _ when pt == typeof(DateOnly) || pt == typeof(DateOnly?):
|
|
case var _ when pt == typeof(DateOnly) || pt == typeof(DateOnly?):
|
|
|
- return DateOnly.TryParse(value.GetText(), out var dateOnlyValue) ? dateOnlyValue : default;
|
|
|
|
|
|
|
+ DateOnly.TryParse(value.GetText(), out var dateOnlyValue);
|
|
|
|
|
+ return dateOnlyValue;
|
|
|
case { IsEnum: true }:
|
|
case { IsEnum: true }:
|
|
|
case var _ when Nullable.GetUnderlyingType(pt) is { IsEnum: true }:
|
|
case var _ when Nullable.GetUnderlyingType(pt) is { IsEnum: true }:
|
|
|
return HandleEnum(value, property, Nullable.GetUnderlyingType(property.PropertyType));
|
|
return HandleEnum(value, property, Nullable.GetUnderlyingType(property.PropertyType));
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- return value.GetText();
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return value.GetText();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static object? GetSpecificNumberType(XLCellValue value, PropertyInfo? property)
|
|
private static object? GetSpecificNumberType(XLCellValue value, PropertyInfo? property)
|
|
@@ -71,7 +73,7 @@ public static class TypeExtensions
|
|
|
throw;
|
|
throw;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Borrowed from https://github.com/ClosedXML/ClosedXML/blob/develop/ClosedXML/Excel/XLCellValue.cs#L361
|
|
// Borrowed from https://github.com/ClosedXML/ClosedXML/blob/develop/ClosedXML/Excel/XLCellValue.cs#L361
|
|
|
public static object? ToObject(this XLCellValue value, PropertyInfo? property = null)
|
|
public static object? ToObject(this XLCellValue value, PropertyInfo? property = null)
|
|
|
{
|
|
{
|
|
@@ -105,16 +107,30 @@ public static class TypeExtensions
|
|
|
public static void SetPropertyValue<T>(this T currentObject, PropertyInfo property, XLCellValue value)
|
|
public static void SetPropertyValue<T>(this T currentObject, PropertyInfo property, XLCellValue value)
|
|
|
{
|
|
{
|
|
|
var valueToSet = value.ToObject(property);
|
|
var valueToSet = value.ToObject(property);
|
|
|
- if (valueToSet == null) return;
|
|
|
|
|
|
|
|
|
|
try
|
|
try
|
|
|
{
|
|
{
|
|
|
property.SetValue(currentObject, valueToSet);
|
|
property.SetValue(currentObject, valueToSet);
|
|
|
}
|
|
}
|
|
|
- catch
|
|
|
|
|
|
|
+ catch (ArgumentException ex) // Catches issues like type mismatch or null for non-nullable
|
|
|
{
|
|
{
|
|
|
- valueToSet = value.ToString();
|
|
|
|
|
- property.SetValue(currentObject, valueToSet);
|
|
|
|
|
|
|
+ // If the property type is string, try to set it directly from the XLCellValue's string representation.
|
|
|
|
|
+ if (property.PropertyType == typeof(string))
|
|
|
|
|
+ {
|
|
|
|
|
+ property.SetValue(currentObject, value.ToString());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ // If it's not a string property, and the initial assignment failed,
|
|
|
|
|
+ // re-throw with more context.
|
|
|
|
|
+ throw new InvalidCastException($"Could not set property '{property.Name}' of type '{property.PropertyType.Name}' with value '{valueToSet}' (original XLCellValue: '{value}'). " +
|
|
|
|
|
+ $"The value returned by ToObject was incompatible, and the property type is not string for fallback conversion. See inner exception for details.", ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex) // Catch any other unexpected exceptions from SetValue
|
|
|
|
|
+ {
|
|
|
|
|
+ throw new InvalidOperationException($"An unexpected error occurred while setting property '{property.Name}' of type '{property.PropertyType.Name}'. " +
|
|
|
|
|
+ $"Value attempted to set: '{valueToSet}' (original XLCellValue: '{value}'). See inner exception for details.", ex);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|