MVC 3 Password Length DataAnnotation

Tags: asp.net-mvc-3, membership-provider, asp.net, c#

I was working with a new MVC 3 project recently and noticed that, after the ASP.NET MVC 3 Tools Update, the AccountModel has been updated. Gone are many of the methods, and the project template is more like the old ASP.NET Web Forms applications in that all the Membership methods are built into the framework. This however has caused a bit of a problem regarding validating the length of the password field.

If you are working with the standard Membership provider, then you will see the option to set the minimum password length from within the web.config;

<membership>
  <providers>
    <clear />
    <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" 
         enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
         maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" 
         passwordAttemptWindow="10" applicationName="/" />
  </providers>
</membership>

However from the new MVC 3 Project template "Internet Application", you will see that the AccountModel has the following code;

[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { getset; }

The Problem

So what happens when you decide that you want to change minimum length of the password once your project has been published? Well you have to change this in two places. THEN re-published your app, and upload to your live site. OUCH

The Solution

I am not sure if this change has been a deliberate one, or just a mistake. A simple fix though is to revert back to using a DataAnnotation which was present priot to the update. I have taken the code from the pre-MVC 3 Tools Update and tweeked it slightly to give you greater control over the error message.

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter , AllowMultiple = false, Inherited = true)]
public sealed class MinRequiredPasswordLengthAttribute : ValidationAttributeIClientValidatable
{                        
    private readonly int _minimumLength = Membership.MinRequiredPasswordLength;        
    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, _minimumLength);
    } 
    public override bool IsValid(object value)
    {           
        string password = value.ToString();
        return password.Length >= this._minimumLength;            
    }        
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new[]{
            new ModelClientValidationStringLengthRule(FormatErrorMessage(metadata.GetDisplayName()), _minimumLength, int.MaxValue)
        };
    } 
}

Then update your AccountModel to use the MinRequiredPasswordLength DataAnnotation instead.

[Required]        
[MinRequiredPasswordLength(ErrorMessage = "The {0} must be at least {1} character(s) long.")]           
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { getset; }

Now when you want to change the minimum length of the password you simply need to change it in the web.config.

PLEASE LEAVE COMMENTS! I am always interested in hearing back from those who read my blog. Please leave a comment if you found this useful, want to suggest any changes to my code, or anything else! Thanks!

3 Comments

  • David Pool said

    I really don't understand why the Account Model was updated without this code. To me it seems as though it is a vital part of linking the web.config with the Model.

    Thanks, for sharing!

  • Sam said

    This is nice,
    I was searching for a solution like yours then I realized that with .NET 4.5 you can use the MembershipPassword attribute
    http://msdn.microsoft.com/en-us/library/system.web.security.membershippasswordattribute(v=vs.110).aspx

Comments have been disabled for this content.

Fork me on GitHub