问题
I've implemented some basic, custom membership provider for my ASP.NET MVC application so I thought that all validation will be done in my custom code.
Unfortunately when I'm trying to create new user by calling function:
Membership.CreateUser(user.UserName, user.Password, user.Email, null, null, true, Guid.NewGuid(), out status);
which should eventually throw an exception with all validation errors I'm getting a status like "InvalidUserName" or "InvalidPassword" instead... That means that my custom CreateUser function isn't call directly, it's used after some basic validation which I would wish to skip.
My CreateUser function (in my custom provider):
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
try
{
User user = new User();
user.UserKey = Guid.NewGuid();
user.UserName = username;
user.passwordSalt = string.Empty;
user.Password = this.TransformPassword(password, ref user.passwordSalt);
user.Email = email;
user.PasswordQuestion = passwordQuestion;
user.PasswordAnswer = passwordAnswer;
user.CreationDate = DateTime.Now;
user.LastActivityDate = DateTime.Now;
user.LastLoginDate = DateTime.MinValue;
user.LastPasswordChangeDate = DateTime.Now;
this._UsersRepository.SaveUser(user);
status = MembershipCreateStatus.Success;
return CreateMembershipFromInternalUser(user);
}
catch(RuleException ex)
{
throw ex;
}
}
Do you know how to enforce direct usage of custom CreateUser function !?
But I'm not using a default ASP.NET MVC project's AccountController...
Just take a look:
[AcceptVerbs(HttpVerbs.Post)]
public ViewResult Register(User user, string password_confirm, bool acceptsTerms)
{
if (!acceptsTerms)
ModelState.AddModelError("acceptsTerms", "Musisz zaakceptować regulamin");
if (ModelState.IsValid)
{
try
{
MembershipCreateStatus status = new MembershipCreateStatus();
Membership.CreateUser(user.UserName, user.Password, user.Email, null, null, true, Guid.NewGuid(), out status);
}
catch (RuleException ex){
ex.CopyToModelState(ModelState,"user");
}
}
return View();
}
The point is that I'm getting a status instead of RuleException ex when user.UserName or user.Password is empty. My custom RuleException ex would give me back such informations as well. Where a status value is assigned right now !? Bacouse it's not done in my implementation of CreateUser...
回答1:
I am using this (MVC3) and I have no issues:
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
MembershipCreateStatus status;
Membership.Provider.CreateUser(model.UserName, model.Password, model.Email, "", "", true, Guid.NewGuid(), out status);
if (status == MembershipCreateStatus.Success)
{
FormsService.SignIn(model.UserName, false);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", AccountValidation.ErrorCodeToString(status));
}
}
// If we got this far, something failed, redisplay form
ViewBag.PasswordLength = MembershipService.MinPasswordLength;
return View(model);
}
回答2:
Using ILSpy to view the static method Membership.CreateUser, you will find it performs validation on
- Username (trim whitespace + not null, not empty)
- Password (trim whitespace + not null, not empty, length checks)
- Email (trim whitespace)
- Password Question (trim whitespace + not empty)
- Password Answer (trim whitespace + not empty)
It then calls the custom provider.
The key here is to not call the static method CreateUser
Membership.CreateUser(...)
Rather, call the custom provider directly by using:
Membership.Provider.CreateUser(...)
Tested and verified working, as of .NET 4
While my site recommends having a password, we support openid. So forcing a user to have a password just seemed counter to what openid is good for.
回答3:
Complete rewrite
The ASP.NET Membership system always does some initial validation of the inputs when APIs such as CreateUser are called.
I don't know of any way around this aside from not going directly to the ASP.NET membership APIs.
来源:https://stackoverflow.com/questions/2038695/asp-net-mvc-custom-membership-provider-createuser