Help123
Help123

Reputation: 1443

ASP.NET Core 2.0 Identity - password error message not showing in view

I'm having a problem using the default ASP.NET Identity service. Everything is working but when trying to register for an account, if the password complexity is not met, no error messages are displayed.

I ran the debugger, and below is the error that is thrown:

result  {Failed : PasswordTooShort,PasswordRequiresDigit,PasswordRequiresUpper,PasswordRequiresUniqueChars} Microsoft.AspNetCore.Identity.IdentityResult

The error message is not passed into the view to be displayed on the Password field. How do you pass the errors into the view? I can manually create a modelstate error but would like the pre-configured messages to be passed in instead.

**Update, I am able to pull in the error messages but trying to solve how to pass all messages into the view. Right now, the view only displays the first error message. Do I need to loop through all the error messages in the view to do that? If so, what would be the best approach?


I have configured the services as below in my startup.cs:

public void ConfigureServices(IServiceCollection services)
        {

            services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));


            services.AddIdentity<IdentityUser, IdentityRole>()
                    .AddEntityFrameworkStores<AppDbContext>();

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit = true;
                options.Password.RequiredLength = 8;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = true;
                options.Password.RequireLowercase = false;
                options.Password.RequiredUniqueChars = 6;
            });
            services.AddTransient<IFeedbackRepository, FeedbackRepository>();
            services.AddTransient<IPieRepository, PieRepository>();
            services.AddMvc();
        }

My Account controller is configured as below:

public class AccountController : Controller
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly UserManager<IdentityUser> _userManager;


            public AccountController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager)
            {
                _signInManager = signInManager;
                _userManager = userManager;
            }
    
            public IActionResult Register()
            {
                return View(new LoginViewModel());
            }
    
    
             [HttpPost]
    public async Task<IActionResult> Register(LoginViewModel loginViewModel)
    {
        if (ModelState.IsValid)
        {
            var user = new IdentityUser() { UserName = loginViewModel.UserName };
            var result = await _userManager.CreateAsync(user, loginViewModel.Password);

            if (result.Succeeded)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                var errList = "";
                var error = result.Errors.ToList(); //convert to list

                foreach (var err in error) //iterate through individual error
                {
                    this.ModelState.AddModelError("Password", err.Description); //add error to modelstate
                    //errList += string.Join(", ", err.Description);
                }
                //this.ModelState.AddModelError("Password", errList);

            }
        }


        return View(loginViewModel);
    }

The loginviewmodel is configured as:

        public class LoginViewModel
        {
            [Key]
            [Required]
            [Display(Name ="User Name")]
            public string UserName { get; set; }
    
            [Required]
            [DataType(DataType.Password)]
            public string Password { get; set; }
        }
    }

The View for register is configured as:

@model LoginViewModel

<h2>Register</h2>

<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Register" asp-controller="Account" method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="UserName" class="control-label"></label>
                <input asp-for="UserName" class="form-control" />
                <span asp-validation-for="UserName" class="text-danger"></span><br />
                <label asp-for="Password" class="control-label"></label>
                <input asp-for="Password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Register" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

Upvotes: 2

Views: 3609

Answers (1)

Wiktor Zychla
Wiktor Zychla

Reputation: 48230

I can't validate this easily (no compiler/vs at hand) but you could try to add the model error in an explicit way before you render the view again

if (result.Succeeded)
{
    return RedirectToAction("Index", "Home");
}
else
{
    var error = string.Join( ", ", result.Errors );

    this.ModelState.AddModelError( "Password", error );
}

Upvotes: 2

Related Questions