Ah… there is one left. We do not only want to remove properties form the model state the typed way. What about adding error messages?

Here we go:

using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;

namespace devcoach.Web.Mvc
{
    /// <summary>
    /// Extensions for the <see cref="ModelStateDictionary"/> class.
    /// </summary>
    public static class ModelStateDictionaryExtensions
    {
        /// <summary>
        /// Removes the specified member from the  <see cref="ModelStateDictionary"/>.
        /// </summary>
        /// <param name="me">Me.</param>
        /// <param name="lambdaExpression">The lambda expression.</param>
        public static void Remove<TViewModel>(
            this ModelStateDictionary me,
            Expression<Func<TViewModel, object>> lambdaExpression)
        {
            me.Remove(GetPropertyName(lambdaExpression));
        }


        /// <summary>
        /// Adds the model error.
        /// </summary>
        /// <typeparam name="TViewModel">The type of the view model.</typeparam>
        /// <param name="me">Me.</param>
        /// <param name="lambdaExpression">The lambda expression.</param>
        /// <param name="errorMessage">The error message.</param>
        public static void AddModelError<TViewModel>(
            this ModelStateDictionary me,
            Expression<Func<TViewModel, object>> lambdaExpression,
            string errorMessage)
        {
            me.AddModelError(GetPropertyName(lambdaExpression), errorMessage);
        }

        /// <summary>
        /// Adds the model error.
        /// </summary>
        /// <typeparam name="TViewModel">The type of the view model.</typeparam>
        /// <param name="me">Me.</param>
        /// <param name="lambdaExpression">The lambda expression.</param>
        /// <param name="exception">The exception.</param>
        public static void AddModelError<TViewModel>(
            this ModelStateDictionary me,
            Expression<Func<TViewModel, object>> lambdaExpression,
            Exception exception)
        {
            me.AddModelError(GetPropertyName(lambdaExpression), exception);
        }



        /// <summary>
        /// Gets the name of the property.
        /// </summary>
        /// <param name="lambdaExpression">The lambda expression.</param>
        /// <returns></returns>
        private static string GetPropertyName(this Expression lambdaExpression)
        {
            var e = lambdaExpression;

            while (true)
            {
                switch (e.NodeType)
                {
                    case ExpressionType.Lambda:
                        e = ((LambdaExpression)e).Body;
                        break;

                    case ExpressionType.MemberAccess:
                        var propertyInfo =
                            ((MemberExpression)e).Member
                            as PropertyInfo;

                        return propertyInfo != null
                                   ? propertyInfo.Name
                                   : null;

                    case ExpressionType.Convert:
                        e = ((UnaryExpression)e).Operand;
                        break;

                    default:
                        return null;
                }
            }
        }
    }
}