Model Binding using Expression Trees

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; }

This article is part of the GWB Archives. Original Author: Jon Canning

New on Geeks with Blogs