Category Archives: Reflector
Quick Commerce Server Post – NotSupportedException on ResetPassword
As the resident CS go-to guy, I was hit up with a bug about a whacky exception message that was exposed whenever a user tried to reset their password. The stack trace resembled the following:
…
System.NotSupportedException – Microsoft.CommerceServer.Runtime, Specified method is not supported.
at Microsoft.CommerceServer.Runtime.Profiles.UpmMembershipUser.ValidateUserAnswer(String answer)
at Microsoft.CommerceServer.Runtime.Profiles.UpmMembershipUser.ResetPassword(String passwordAnswer)
…
After staring at it for a couple of minutes and looking precisely at where we called it for a while I opened Reflector and gave it a crack. The UpmMembershipProvider and associated classes are in Microsoft.CommerceServer.Runtime.dll, found in C:\Program Files\Microsoft Commerce Server 2007\Assemblies.
Looking at UpmMembershipUser.ValidateUserAnswer(string answer), I found it used a variable called RequiresQuestionAndAnswer to determine whether validating the answer is required and throws a NotSupportedException if it is not. This variable was set in the UpmMembershipSettings class’ GetProfileConfiguration() method as follows:
this.requiresQuestionAndAnswer =
inspector.DoesProfilePropertyExist("GeneralInfo.password_question", "STRING")
&& inspector.DoesProfilePropertyExist("GeneralInfo.password_answer", "STRING");
This tells me that the way we determine whether we require a Question/Answer combination to reset the password is actually by seeing whether the question and answer properties are exposed on the UserObject profile. Much to my dismay, these properties had been removed by someone…
Looking at the code again, I realised that an empty string was being passed through to ResetPassword because a custom answer validation was being performed in code before that. In the end, simply removing the parameter or passing null fixed this issue because ResetPassword() calls ResetPassword(null) which causes another branch to be executed that does not call the method ValidateAnswer.
Doing a quick search through the codebase revealed that there was another part of the system that called the method without a parameter. In fact, the same 3 lines were repeated almost exactly…
string generatedPassword = membershipUser.ResetPassword();
membershipUser.ChangePassword(generatedPassword, e.NewPassword);
membershipProvider.UpdateUser(membershipUser);
Lessons learnt:
- Reflector is AWESOME!
- Put common code in an accessible place…