2

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!

LukeP
  • 10,422
  • 6
  • 29
  • 48
  • You forgot "override" on the CreateUser method. Also, [this](http://theintegrity.co.uk/2010/11/asp-net-mvc-2-custom-membership-provider-tutorial-part-1/) is an excellent tutorial on defining your entire custom membership provider. Cheers! – vvohra87 Oct 16 '11 at 13:28
  • 1
    Thanks. I've worked it out with some help. Funny though, the link is actually my blog and my tutorial ;) – LukeP Oct 19 '11 at 21:16
  • Seriously! Woah, in that case thanks a million mate. That tutorial is the first time I attempted to even try to use Forms Authentication! It helped me a great deal. Much owed. – vvohra87 Oct 21 '11 at 07:11
  • @LukeP THATS GREAT ARTICLE BUT GETTING ERROR AT Models/AccountModels.cs file error is Error 1 Cannot implicitly convert type 'System.Web.Security.MembershipProvider' to 'MvcMembership.Models.MyMembershipProvider'. An explicit conversion exists (are you missing a cast?) – Neo Jan 05 '12 at 10:47
  • @ashuthinks I believe the tutorial was written for MVC 2 and I believe you would be using MVC 3 now. Few things have changed. Can you open a new question and mention exactly which line of code is failing? I still got the source code. I'll try to look into it. – LukeP Jan 05 '12 at 23:18

2 Answers2

4

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).

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • I think your previous (pre-edit) answer was more on the point. From MSDN: "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. ". How do I cast MembershipProvider instance as my custom membership provider type? – LukeP Apr 30 '11 at 00:58
  • Yes, you can cast the MembershipProvider instance, but not the Membership static class. I tried to clarify this in my edit. – Erik Funkenbusch Apr 30 '11 at 01:01
1

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;
        }

Adam Tuliper
  • 29,982
  • 4
  • 53
  • 71
  • I'm trying to implement custom Membership Provider with custom MembershipUser to be able to store first and last name in it. I don't want to use Profile provider. I want to overload the CreateUser method like shown in: http://msdn.microsoft.com/en-us/library/ms366730%28v=VS.100%29.aspx in "Modify the CreateUser Method" paragraph. The example doesn't show how this method is called from within a controller which I think is what I am missing. – LukeP Apr 30 '11 at 00:50
  • ah ok - I edited answer above since you dont want a profile property – Adam Tuliper Apr 30 '11 at 01:42
  • Thanks. Worked it out from Mystere Man's answer. – LukeP Apr 30 '11 at 01:48