object Bind(object requestDto, NameValueCollection formData)
{
var propertyGroups = formData.AllKeys.Where(x => x.Contains('.')).GroupBy(x => x.Substring(0, x.IndexOf('.')));
foreach (var group in propertyGroups)
{
var propertyName = group.Key;
var propertyInfo = requestDto.GetType().GetProperty(propertyName);
var propertyType = propertyInfo.PropertyType;
var bindings = new List<MemberBinding>();
foreach (var childPropertyKey in group)
{
var childPropertyName = childPropertyKey.Substring(childPropertyKey.IndexOf('.') + 1);
var childPropertyInfo = propertyType.GetProperty(childPropertyName);
var childPropertyType = childPropertyInfo.PropertyType;
if (!childPropertyType.IsPrimitive) continue;
var childPropertyValueString = formData[childPropertyKey];
var parseExpression = Expression.Call(childPropertyType.GetMethods().Single(x => x.Name == "Parse" && x.GetParameters().Count() == 1), Expression.Constant(childPropertyValueString));
var childPropertyValue = Expression.Lambda(parseExpression).Compile().DynamicInvoke();
bindings.Add(Expression.Bind(childPropertyInfo, Expression.Constant(childPropertyValue)));
}
Expression memberInit = Expression.MemberInit(Expression.New(propertyType), bindings);
var propertyValue = Expression.Lambda(memberInit).Compile().DynamicInvoke();
var propertyExpression = Expression.Property(Expression.Constant(requestDto), propertyInfo);
var assignExpression = Expression.Assign(propertyExpression, Expression.Constant(propertyValue));
Expression.Lambda(assignExpression, Expression.Parameter(requestDto.GetType())).Compile().DynamicInvoke(requestDto);
}
return requestDto;
}