private static void ConvertPropertyValue(PropertyConvertContext context) { if (!context.Options.Convert(context)) { context.Value = ConvertPropertyValue(context.Value, context.SourceProperty.Type, context.TargetProperty.Type, context.TargetProperty, context); } }
private static void SetPropertyValue(ModelPropertyInfo mp1, PropertyConvertContext context, object state) { if (!mp1.IsCollection /*|| mp1.Type.IsAssignableFrom(value.GetType()) && !mp1.IsReadOnly*/) { SetValueScalar(context); } else { SetValueCollection(context); } }
internal static void WalkConvertiblProperties(object target, ModelInfo targetInfo, object source, ModelInfo sourceInfo, ModelConvertOptions options, Action <ModelPropertyInfo, PropertyConvertContext, object> callback, object state) { foreach (var mp1 in targetInfo.Properties) { var mp0 = MapProperty(mp1, sourceInfo, options); if (mp0.Length > 0 && options.ShouldSetValue(mp1)) { PropertyConvertContext context = new PropertyConvertContext(source, mp0, target, mp1, GetValue(mp0, source), options); callback(mp1, context, state); } } }
private static bool CheckReadOnly(PropertyConvertContext context) { if (context.TargetProperty.IsReadOnly) { if (!context.Options.ShouldIgnoreReadOnly(context.TargetProperty)) { throw new InvalidOperationException($"The property {context.TargetModel.ModelType}.{context.TargetProperty.Name} is read-only."); } else { return(true); } } return(false); }
internal bool Convert(PropertyConvertContext context) { var source = GetSourceProperty(context.SourceProperty); var ok = false; if (source != null && source.Converter != null) { context.Value = source.Converter(context.Value, context); ok = true; } else { var options = GetTargetProperty(context.TargetProperty); if (options != null && options.Converter != null) { context.Value = options.Converter(context.Value, context); ok = true; } } return(ok); }
private static void SetValueScalar(PropertyConvertContext context) { if (CheckReadOnly(context)) { return; } ConvertPropertyValue(context); object value = context.Value; if (value == null) { Type type = context.TargetProperty.Type; if (!type.CanBeNull()) { value = context.Options.GetDefaultValue(context) ?? type.DefaltValue(); //throw new InvalidOperationException($"Try to set null value to a property which cannot be null. Property = {mp1.PropertyInfo.DeclaringType}.{mp1.Name}"); } } context.TargetProperty.SetValue(context.Target, value); }
private static object ConvertPropertyValue(object source, Type sourceType, Type targetType, ModelPropertyInfo property, PropertyConvertContext context) { if (source == null || targetType.IsAssignableFrom(sourceType)) { return(source); } TypeConverter converter; if (property == null) { converter = TypeDescriptor.GetConverter(targetType); } else { converter = property.GetConverter(); } if (converter != null && converter.CanConvertTo(targetType)) { return(converter.ConvertTo(source, targetType)); } Type type; if ((type = Nullable.GetUnderlyingType(targetType)) != null) { if (type == source.GetType()) { return(source); } } try { return(System.Convert.ChangeType(source, targetType)); } catch { } if (sourceType.IsClass && targetType.IsClass) { return(Convert(source, sourceType, targetType, context.Options)); } throw new InvalidOperationException($"Cannot convert type from {source.GetType()} to {targetType}."); }
private static void SetValueCollection(PropertyConvertContext context) { var collInfo = context.TargetProperty.CollectionInfo; ArrayList coll0; bool man = collInfo.SupportManipulation; if (!context.SourceProperty.IsCollection) { throw new InvalidOperationException($"The source property {context.SourceModel.ModelType}.{context.SourceProperty.Name} is not a collection type."); } if (context.Value != null) { var wrapper = context.SourceProperty.CollectionInfo.CreateWrapper(context.Value); var filter = context.Options.GetFilter(context.SourceProperty); coll0 = new ArrayList(wrapper.Count); foreach (object v in wrapper) { if (filter?.Invoke(v, context) ?? true) { var tv = ConvertPropertyValue(v, context.SourceProperty.CollectionInfo.ElementType ?? typeof(object), collInfo.ElementType ?? typeof(object), null, context); coll0.Add(tv); } } } else { SetValueScalar(context); return; } if (collInfo.IsArray) { man = false; context.Value = coll0.ToArray(collInfo.ElementType ?? typeof(object)); SetValueScalar(context); } else if (man) { var tv = context.TargetProperty.GetValue(context.Target); ICollectionWrapper coll1; if (tv != null) { coll1 = collInfo.CreateWrapper(tv); coll1.Clear(); } else { coll1 = collInfo.CreateWrapper(); } foreach (object v in coll0) { coll1.Add(v); } if (tv == null) { context.Value = coll1.RawCollection; SetValueScalar(context); } } else { throw new NotSupportedException("Collection type conversion for " + context.TargetProperty.Type + " is not supported yet."); } //if (collInfo.SupportManipulation) //{ // object tv = context.TargetProperty.GetValue(context.TargetProperty); // if (tv != null) // { // var coll1 = collInfo.CreateWrapper(tv); // coll1.Clear(); // if (coll0 != null) // { // foreach (object v in coll0) // coll1.Add(v); // } // return; // } //} //if (CheckReadOnly(context)) // return; //if (coll0 == null) //{ // SetValueScalar(context); // return; //} //object value; //// 如果是数组,创建一个新的数组并赋值。 //if (collInfo.IsArray) //{ // Array array = Array.CreateInstance(collInfo.ElementType, coll0.Count); // int index = 0; // foreach (var v in coll0) // array.SetValue(v, index); // value = array; // return; //} //if (collInfo.ObjectType.IsInterface) //{ // // 如果是接口,创建一个List`1或ArrayList // IList list; //} //else //{ // // 直接创建集合的实例,并进行逐一添加 // value = ModelInfo.GetModelInfo(collInfo.ObjectType).CreateInstance(); //} }
internal object GetDefaultValue(PropertyConvertContext context) { return(GetTargetProperty(context.TargetProperty)?.DefaultValue); }