Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit e24e7f3

Browse files
committed
Fix an issue with nullable Enum to Enum conversion
In case of conversion from SomeEnum? to SomeEnum type property there was an error, causing property to be populates with default Enum value instead of correct one. Fixed by adding if-cases to CreateTypeConverter code.
1 parent 6b08d8c commit e24e7f3

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

src/ServiceStack.Text/AutoMappingUtils.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static T ConvertTo<T>(this object from)
2727

2828
if (from.GetType().IsValueType())
2929
{
30-
return (T)Convert.ChangeType(from, typeof(T), provider:null);
30+
return (T)Convert.ChangeType(from, typeof(T), provider: null);
3131
}
3232

3333
if (typeof(IEnumerable).IsAssignableFromType(typeof(T)))
@@ -699,7 +699,7 @@ public static PropertyGetterDelegate CreateTypeConverter(Type fromType, Type toT
699699
{
700700
if (toType.IsEnum() && fromType.IsEnum())
701701
{
702-
return fromValue => Enum.Parse(toType, fromValue.ToString(), ignoreCase:true);
702+
return fromValue => Enum.Parse(toType, fromValue.ToString(), ignoreCase: true);
703703
}
704704
if (toType.IsNullableType())
705705
{
@@ -711,11 +711,25 @@ public static PropertyGetterDelegate CreateTypeConverter(Type fromType, Type toT
711711
}
712712
else if (toType.IsIntegerType())
713713
{
714+
if (fromType.IsNullableType())
715+
{
716+
var genericArg = fromType.GenericTypeArguments()[0];
717+
if (genericArg.IsEnum())
718+
{
719+
return fromValue => Enum.ToObject(genericArg, fromValue);
720+
}
721+
}
714722
return fromValue => Enum.ToObject(fromType, fromValue);
715723
}
716724
}
717725
else if (toType.IsNullableType())
718726
{
727+
var toTypeBaseType = toType.GenericTypeArguments()[0];
728+
if (toTypeBaseType.IsEnum())
729+
{
730+
if (fromType.IsEnum() || (fromType.IsNullableType() && fromType.GenericTypeArguments()[0].IsEnum()))
731+
return fromValue => Enum.ToObject(toTypeBaseType, fromValue);
732+
}
719733
return null;
720734
}
721735
else if (typeof(IEnumerable).IsAssignableFromType(fromType))
@@ -730,13 +744,13 @@ public static PropertyGetterDelegate CreateTypeConverter(Type fromType, Type toT
730744
}
731745
else if (toType.IsValueType())
732746
{
733-
return fromValue => Convert.ChangeType(fromValue, toType, provider:null);
747+
return fromValue => Convert.ChangeType(fromValue, toType, provider: null);
734748
}
735749
else
736750
{
737-
return fromValue =>
751+
return fromValue =>
738752
{
739-
if (fromValue == null)
753+
if (fromValue == null)
740754
return fromValue;
741755

742756
var toValue = toType.CreateInstance();

tests/ServiceStack.Text.Tests/AutoMappingTests.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ public class NullableEnumConversion
9393
public Color Color { get; set; }
9494
}
9595

96+
public class ReallyNullableEnumConversion
97+
{
98+
public Color? Color { get; set; }
99+
}
100+
96101
public class EnumConversion
97102
{
98103
public Color Color { get; set; }
@@ -209,7 +214,6 @@ public void Does_Enumnullableconversion_translate()
209214
var conversionDto = conversion.ConvertTo<NullableEnumConversionDto>();
210215

211216
Assert.That(conversionDto.Color, Is.EqualTo(OtherColor.Green));
212-
213217
}
214218

215219
[Test]
@@ -221,6 +225,33 @@ public void Does_Enumconversion_translate()
221225
Assert.That(conversionDto.Color, Is.EqualTo(OtherColor.Green));
222226
}
223227

228+
[Test]
229+
public void Does_ReallyEnumnullableconversion_translate()
230+
{
231+
var conversion = new ReallyNullableEnumConversion { Color = Color.Green };
232+
var conversionDto = conversion.ConvertTo<NullableEnumConversionDto>();
233+
234+
Assert.That(conversionDto.Color, Is.EqualTo(OtherColor.Green));
235+
}
236+
237+
[Test]
238+
public void Does_RealyEnumconversion_translate()
239+
{
240+
var conversion = new ReallyNullableEnumConversion { Color = Color.Green };
241+
var conversionDto = conversion.ConvertTo<EnumConversionDto>();
242+
243+
Assert.That(conversionDto.Color, Is.EqualTo(OtherColor.Green));
244+
}
245+
246+
[Test]
247+
public void Does_Enumconversion_translateFromNull()
248+
{
249+
var conversion = new ReallyNullableEnumConversion { Color = null };
250+
var conversionDto = conversion.ConvertTo<EnumConversionDto>();
251+
252+
Assert.That(conversionDto.Color, Is.EqualTo(default(OtherColor)));
253+
}
254+
224255
[Test]
225256
public void Does_translate_nullableInt_to_and_from()
226257
{

0 commit comments

Comments
 (0)