public static void Populate(IDictionary <string, object> source, object target, out ICollection <ConvertProblem> problems, params object[] populated) { Guard.NotNull(source, nameof(source)); Guard.NotNull(target, nameof(target)); problems = new List <ConvertProblem>(); if (populated.Any(x => x == target)) { return; } Type t = target.GetType(); if (source != null) { foreach (var fastProp in FastProperty.GetProperties(t).Values) { object value; var pi = fastProp.Property; if (!pi.PropertyType.IsPredefinedSimpleType() && source.TryGetValue(pi.Name, out value) && value is IDictionary <string, object> ) { var nestedValue = fastProp.GetValue(target); ICollection <ConvertProblem> nestedProblems; populated = populated.Concat(new object[] { target }).ToArray(); Populate((IDictionary <string, object>)value, nestedValue, out nestedProblems, populated); if (nestedProblems != null && nestedProblems.Any()) { problems.AddRange(nestedProblems); } WriteToProperty(target, fastProp, nestedValue, problems); } else if (pi.PropertyType.IsArray && !source.ContainsKey(pi.Name)) { WriteToProperty(target, fastProp, RetrieveArrayValues(pi, source, problems), problems); } else { if (source.TryGetValue(pi.Name, out value)) { WriteToProperty(target, fastProp, value, problems); } } } } }
// REVIEW: Dieser Code ist redundant mit DefaultModelBinder u.Ä. Entweder ablösen oder eliminieren (vielleicht ist es ja in diesem Kontext notwendig!??!) private static object RetrieveArrayValues(PropertyInfo arrayProp, IDictionary <string, object> source, ICollection <ConvertProblem> problems) { Type elemType = arrayProp.PropertyType.GetElementType(); bool anyValuesFound = true; int idx = 0; var elements = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(elemType)); var properties = FastProperty.GetProperties(elemType); while (anyValuesFound) { object curElement = null; anyValuesFound = false; // false until proven otherwise foreach (var prop in properties.Values) { //var key = string.Format("_{0}{1}_{2}", idx, arrayProp.Name, pd.Name); var key = string.Format("{0}[{1}].{2}", arrayProp.Name, idx, prop.Name); object value; if (source.TryGetValue(key, out value)) { anyValuesFound = true; if (curElement == null) { curElement = Activator.CreateInstance(elemType); elements.Add(curElement); } SetPropFromValue(value, curElement, prop, problems); } } idx++; } var elementArray = Array.CreateInstance(elemType, elements.Count); elements.CopyTo(elementArray, 0); return(elementArray); }