I’m currently working with Philip on a project which also has an ASP.NET MVC (by the way I really like the .MVC idea somebody came up the last weeks) project. We came to the point where we needed to remove the required property “Password” if the user is registering using OAuth.

Argh. That’s is not typed!

So I wrote a small extension method that I added to the devcoach.Web.Mvc assembly I’d like to share here:

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

Using the extension method you can use the following fully typed syntax inside your controllers:

[HttpPost]
public ActionResult Registration(AccountRegistrationViewModel model)
{
    if (model.IsTokenRegistration)
    {
        ModelState.Remove<AccountRegistrationViewModel>(t => t.Password);
        ModelState.Remove<AccountRegistrationViewModel>(t => t.RetypePassword);
    }
    //...
}