简体   繁体   中英

Create user programmatically using C# ASP.NET MVC Identity

I'm trying to add a user programmatically to ASP.NET MVC Identity.

The error I'm encountering is: UserManager threw an exception of type 'System.NullReferenceException'

This function is called through a POST not originating from this site. It sits right below public async Task<ActionResult> Register(RegisterViewModel model) in the AccountController.

[AllowAnonymous]
public async Task<bool> GenerateUser(string email)
{
        var user = new ApplicationUser { UserName = email, Email = email };
        string password = System.Web.Security.Membership.GeneratePassword(12, 4);
        var result = await UserManager.CreateAsync(user, password);

        if (result.Succeeded)
        {
           // Omitted
        }
        else { AddErrors(result); }

        return true;
 }

I have also attempted to use the below code to perform the same action, but I get the error that special characters can't be in the UserName (I am using an email address), but this is definitely allowed as it's how all my users are created using public async Task<ActionResult> Register(RegisterViewModel model) .

string password = System.Web.Security.Membership.GeneratePassword(12, 4);
var store = new Microsoft.AspNet.Identity.EntityFramework.UserStore<ApplicationUser>();
var manager = new ApplicationUserManager(store);
var user = new ApplicationUser() { Email = email, UserName = email };
var result = manager.Create(user, password);

The user object is the same as if I had filled a form to create a new user on the site (using public async Task<ActionResult> Register(RegisterViewModel model) ), and the password is just a string, also the same.


public async Task<ActionResult> Register(RegisterViewModel model) is as per the scaffolded default but here it is below anyway for reference:

// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                //await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);

                // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                 string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                 var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                 await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

                //return RedirectToAction("Index", "Home");
                // TODO: Email Sent
                return View("ConfirmationSent");
            }
            AddErrors(result);
        }

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

Edit:

I call the function with:

var result = new AccountController().GenerateUser(model.emailAddress);

Edit2:

As asked for: This is the class definition for the ApplicationUserManager

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 8,
            RequireNonLetterOrDigit = false,
            RequireDigit = false,
            RequireLowercase = false,
            RequireUppercase = false,
        };

        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;

        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug it in here.
        manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });
        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = 
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}

The issue is with the UserManager, this solves the issue.

    ApplicationDbContext context = new ApplicationDbContext();

    var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
    var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
    UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)
    {
        AllowOnlyAlphanumericUserNames = false,
        RequireUniqueEmail = true
    };

    string password = System.Web.Security.Membership.GeneratePassword(12, 4);
    var user = new ApplicationUser();
    user.Email = model.Email;
    user.UserName = model.Email;

    string userPWD = password;

    var result = UserManager.Create(user, userPWD);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM