ASP.NET MVC Custom Membership Provider - How to ov

2019-01-23 00:57发布

问题:

I'm trying to build Custom Membership Provider. I would like to capture additional information (First Name and Last Name) during the registration and I'm not using usernames (email is a login).

In my custom Membership Provider I'm trying to overload CreateUser method like this:

    public override MyMembershipUser CreateUser(string firstName, string lastName, 
                                       string email, string password)
    {
        ...
    }

But when I want to call it from the Account controller:

    [HttpPost]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            MembershipCreateStatus createStatus;
            Membership.CreateUser(model.FirstName, model.LastName, 
                                  model.Email, model.Password);

            if (createStatus == MembershipCreateStatus.Success)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", ErrorCodeToString(createStatus));
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

I get the error stating that "No overload for method takes 4 arguments".

How do I call my custom CreateUser method from Custom Membership Provider class?

Thank you!

回答1:

Isn't it obvious? You're referencing Membership, not MyMembershipProvider when you call Membership.CreateUser.

It looks like Membership is a static class that internally calls into your membership provider, so there is no real way to change this other than creating your own "MyMembership" static class that does the same thing. Since you can't inherit from static classes, you would have to either call into Membership.XXX from your static version, or implement the functionality yourself.

Your own MyMembership class could then have any methods you wanted it to have.

Another option would be to do something like this:

((MyMembershipProvider)Membership.Provider).CreateUser()

I don't like this approach though because it requires you to remember to call the provider CreateUser rather than the Membership.CreateUser. Plus, casting is often a code smell (unless encapsulated, which is why i recommended your own MyMembership static class).



回答2:

The problem here is the Membership provider class doesn't give you a first and last name. You could store these in the profile however. In that case you need to go into AccountController.cs class and change 1. the interface

    public interface IMembershipService
    {
        int MinPasswordLength { get; }

        bool ValidateUser(string userName, string password);
        MembershipCreateStatus CreateUser(string userName, string password, string email);
        bool ChangePassword(string userName, string oldPassword, string newPassword);
    }

and add a new CreateUser method signature with the fields you want.

Then you will need to implement this method in the AccountController class in that file.

The article you mention below says:

"However, this overload will not be called by the Membership class or controls that rely on the Membership class, such as the CreateUserWizard control. To call this method from an application, cast the MembershipProvider instance referenced by the Membership class as your custom membership provider type, and then call your CreateUseroverload directly. "

So - you cannot call the built in CreateUser as they mention Try casting the call in your new CreateUser method to be

public MembershipCreateStatus CreateUser(string firstName, string lastName, string password, string email)
        {
            if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
            if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");
//etc....
            MembershipCreateStatus status;
((YourCustomProvider)_provider).CreateUser(firstName, lastName, password, email, null, null, true, null, out status);            return status;
        }