William Duffy

Glasgow Based C# ASP.NET Web Developer

Repopulate Html.PasswordFor<> on validation errors

ASP.NET MVC’s HTML helpers are fast and efficient for rendering elements using your model. One of these is the HTML.PasswordFor<> method, which has a little gotcha that many people get caught out with.

The HTML.PasswordFor<> method will render a password input to mask keystrokes on the browser but will not populate the value using the model. For most scenarios this is fine however there are occasions this functionality can be counter productive.

For example, a logged in user may be given the opportunity to update their password. A suitable implementation of this would include three fields in the process.

  1. Current Password
  2. New Password
  3. Confirm New Password

All these fields will be keystroke masked password fields. When the post to your action occurs the model will be validated to ensure the following restrictions are met

  1. Current Password is supplied and is correct
  2. New password is supplied and is within acceptable criteria
  3. Confirm New Password matches New Password exactly

Any of these criteria can fail, at which point the action will return its view with suitable validation errors. The problem exists at this point as┬áthe password field will not be repopulated with the last entered value, instead being reset to blank. Fortunately the solution, although not instantly obvious, is very easy. Simply populate the value manually using Html.PasswordFor’s htmlAttributes parameter and your model.

Html.PasswordFor(x => x.CurrentPassword, new { value = Model.CurrentPassword })

The user can now continue to enter their details from the point that validation failed.

Important Note. Do not pass your original domain model to the view model if you are going to use this method. If you do, the password will always be pre-populated. The view model should have it’s own properties to handle the three password entries and be empty by default.


Tagged as , , , , , , + Categorized as C#, MVC

3 Comments

  1. I would hope you *don’t* pass the password back to the client. It should never do that. Sure you might think you’re helping them but especially in your example you’re passing their “currentpassword” back to the user. This creates a security hole that would allow someone to gain their current password. Since most people use the same password for all their accounts you’ve just told someone who *might* have physical access to this one account (the user stayed logged in or what-not) what their password is for something like their email or banking. never never do this.

  2. @Morder You have a valid point however the risk you mention is negligible. The current password must be freshly entered by the user in order to post the change request, it is not automatically populated from the domain, exists only within the context of the controller action and exists only for the life of the password change operation (I stated this at the end of the post). The user is highly unlikely to walk away from their machine during a password change which they initiate. The same risk could be associated with a user entering their details into a login field and walking away from their machine before pressing the submit button. When the update is successful the user will be redirected and the user is free to leave their machine and do what they wish. Even if they do not log out the password data they submitted will no longer be available. On a side note if someone uses their password on other websites they are leaving themselves wide open in a lot of situations. All it takes is a sign-up email confirmation with their details to be read by a third party to create a security breach.

  3. Oh agreed about the same password issue…I still slightly misunderstood how you were going about it and didn’t really catch that last part…ignore my ranting! :)

Leave a Reply