可为 nullable double 和 int 之间的转换失败
Conversion fails between nullable double and int
我有一个模型 FittingProject
,我正试图将其映射到另一个模型 FittingsProjectSharepointModel
。
不幸的是,FittingProject
和 FittingsProjectSharepointModel
仅共享值,属性 名称和类型都不同。
为了简化映射过程,我为 FittingProject
创建了一个自定义属性,我用它来查找 FittingsProjectSharepointModel
上匹配的 属性。问题是大多数值在转换过程中都会失败,例如从 int
到 double?
。
正如您在下面的代码片段中看到的,我尝试使用 Convert.ChangeType
,但它仍然失败并出现相同的异常。
public ModelMapper MapModelToFittingsProjectSharepointModel(object model)
{
if (model == null)
{
return null;
}
var propertiesWithCustomAttributes = model
.GetType()
.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(SharepointModelPropertyAttribute), true).Length > 0);
foreach (var prop in propertiesWithCustomAttributes)
{
foreach (var customAttribute in prop.GetCustomAttributes(true))
{
SharepointModelPropertyAttribute sharePointModelPropertyAttribute =
customAttribute as SharepointModelPropertyAttribute;
PropertyDescriptor sharePointModelprop = TypeDescriptor
.GetProperties(typeof(FittingsProjectSharepointModel))
.Find(sharePointModelPropertyAttribute.SharepointModelProperty, false);
try
{
var projectValue = prop.GetValue(model);
var projectValueConverted = Convert.ChangeType(projectValue, sharePointModelprop.PropertyType);
sharePointModelprop.SetValue(FittingsProjectSharepointModel, projectValueConverted);
}
catch (Exception ex)
{
//
}
}
}
return this;
}
ChangeType 不支持:
Convert.ChangeType(1234, typeof(double)) //works
Convert.ChangeType(1234, typeof(double?)) //fails
因此您可能需要进行自己的可空处理。只需使用 Nullable.GetUnderlyingType
从目标类型中去除可为 null 的 属性。您还需要处理这种情况,即要转换的值是 null
.
您可以使用 AutoMapper。像这样:
考虑以下示例模型:
public class FittingProject
{
public string Name { get; set; }
public int Size { get; set; }
}
public class FittingsProjectSharepointModel
{
public string Display { get; set; }
public double? Volume { get; set; }
}
现在,您可以像这样在模型之间创建映射:
AutoMapper.Mapper.CreateMap<FittingProject, FittingsProjectSharepointModel>()
.ForMember(dest => dest.Display, opts => opts.MapFrom(src => src.Name)) //Map Name to Display
.ForMember(dest => dest.Volume, opts => opts.MapFrom(src => src.Size)); //Map Size to Volume
转换方法如下:
FittingProject fitting_project = new FittingProject()
{
Name ="project_name",
Size = 16
};
FittingsProjectSharepointModel sharepoint_model =
AutoMapper.Mapper.Map<FittingsProjectSharepointModel>(fitting_project);
我有一个模型 FittingProject
,我正试图将其映射到另一个模型 FittingsProjectSharepointModel
。
不幸的是,FittingProject
和 FittingsProjectSharepointModel
仅共享值,属性 名称和类型都不同。
为了简化映射过程,我为 FittingProject
创建了一个自定义属性,我用它来查找 FittingsProjectSharepointModel
上匹配的 属性。问题是大多数值在转换过程中都会失败,例如从 int
到 double?
。
正如您在下面的代码片段中看到的,我尝试使用 Convert.ChangeType
,但它仍然失败并出现相同的异常。
public ModelMapper MapModelToFittingsProjectSharepointModel(object model)
{
if (model == null)
{
return null;
}
var propertiesWithCustomAttributes = model
.GetType()
.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(SharepointModelPropertyAttribute), true).Length > 0);
foreach (var prop in propertiesWithCustomAttributes)
{
foreach (var customAttribute in prop.GetCustomAttributes(true))
{
SharepointModelPropertyAttribute sharePointModelPropertyAttribute =
customAttribute as SharepointModelPropertyAttribute;
PropertyDescriptor sharePointModelprop = TypeDescriptor
.GetProperties(typeof(FittingsProjectSharepointModel))
.Find(sharePointModelPropertyAttribute.SharepointModelProperty, false);
try
{
var projectValue = prop.GetValue(model);
var projectValueConverted = Convert.ChangeType(projectValue, sharePointModelprop.PropertyType);
sharePointModelprop.SetValue(FittingsProjectSharepointModel, projectValueConverted);
}
catch (Exception ex)
{
//
}
}
}
return this;
}
ChangeType 不支持:
Convert.ChangeType(1234, typeof(double)) //works
Convert.ChangeType(1234, typeof(double?)) //fails
因此您可能需要进行自己的可空处理。只需使用 Nullable.GetUnderlyingType
从目标类型中去除可为 null 的 属性。您还需要处理这种情况,即要转换的值是 null
.
您可以使用 AutoMapper。像这样:
考虑以下示例模型:
public class FittingProject
{
public string Name { get; set; }
public int Size { get; set; }
}
public class FittingsProjectSharepointModel
{
public string Display { get; set; }
public double? Volume { get; set; }
}
现在,您可以像这样在模型之间创建映射:
AutoMapper.Mapper.CreateMap<FittingProject, FittingsProjectSharepointModel>()
.ForMember(dest => dest.Display, opts => opts.MapFrom(src => src.Name)) //Map Name to Display
.ForMember(dest => dest.Volume, opts => opts.MapFrom(src => src.Size)); //Map Size to Volume
转换方法如下:
FittingProject fitting_project = new FittingProject()
{
Name ="project_name",
Size = 16
};
FittingsProjectSharepointModel sharepoint_model =
AutoMapper.Mapper.Map<FittingsProjectSharepointModel>(fitting_project);