Bubinga
Bubinga

Reputation: 703

Compare Attribute fails on Post

I have a Register form which uses the Compare Attribute to compare the password and confirm password. When I enter in different passwords it does what it is supposed to and says "Passwords do not match". The issue comes when I hit the submit button and "Post" it. I hit a breakpoint at "if (!ModelState.IsValid)" where ModelState is not valid. When it reloads the page where it used to say "Passwords do not match" it now says "Could not find a property named Password." I tried doing what this post said to try and put in the answer's code. All it returns is that the error is "null". Razor Page:

@page
@model ThinBlueLie.Pages.RegisterModel

@{
    ViewBag.Title = "Register";
}


<div class="container-fluid h-100 row nogap">
    <div class="card border-secondary mx-auto center col-lg-3 col-md-4 p-0" style="margin-top:100px;">
        <div class="card-header">
            Register
            <a class="float-right" asp-page="/Login">Login</a>
        </div>
        <form method="post">
            <div class="card-body text-secondary">
                <div class="form-group">
                    <label asp-for="Users.Email" class="control-label">Email</label>
                    <input type="email" asp-for="Users.Email" class="form-control">
                    <span asp-validation-for="Users.Email" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label  asp-for="Password"class="control-label"></label>
                    <input asp-for="Password" type="password" class="form-control" >
                    <span asp-validation-for="Password" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="ConfirmPassword" class="control-label"></label>
                    <input type="password" asp-for="ConfirmPassword" class="form-control">
                    <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
                </div>                      
                <div class="form-group">
                    <label asp-for="Users.Username" class="control-label"></label>
                    <input type="text" asp-for="Users.Username" class="form-control">
                    <span asp-validation-for="Users.Username" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Register" class="btn btn-primary mb-1" style="float:right" />
                </div>
            </div>
        </form>
        <div class="card-footer">
            <a>Log in with Google</a>
        </div>
    </div>
</div>

@section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    }

PageModel:

namespace ThinBlueLie.Pages
{
    public class RegisterModel : PageModel
    {
        private readonly DataAccessLibrary.thinblue.ThinbluelieContext _context;

        public RegisterModel(DataAccessLibrary.thinblue.ThinbluelieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        
        public Users Users { get; set; }        

        [BindProperty]
        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [Required]
        [BindProperty]
        [DataType(DataType.Password)]
        [Display(Name = "Confirm Password")]
        [Compare("Password", ErrorMessage = "Passwords do not match")]
        public string ConfirmPassword { get; set; }

        // To protect from overposting attacks, enable the specific properties you want to bind to, for
        // more details, see https://aka.ms/RazorPagesCRUD.



        public async Task<IActionResult> OnPostAsync()
        {
            var errors = ModelState.Values.SelectMany(v => v.Errors);
            if (!ModelState.IsValid)
            {
                return Page();
            }           

            _context.Users.Add(Users);
             await _context.SaveChangesAsync();

             return RedirectToPage("./Index");        
         
        }
    }
} 

Model:

namespace DataAccessLibrary.thinblue
{
    public partial class Users
    {
        public int IdUsers { get; set; }

        [BindProperty]
        public string Username { get; set; }

        [BindProperty]
        [Required]
        [EmailAddress]
        public string Email { get; set; }

        
        public string Password { get; set; }
    }
}

Upvotes: 0

Views: 106

Answers (1)

Yiyi You
Yiyi You

Reputation: 18159

I reproduce your error,and I put Password and ConfirmPassword in the same model,and it works.Here is a demo:

PassWordModel:

public class PassWordModel
    {
        [BindProperty]
        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [Required]
        [BindProperty]
        [DataType(DataType.Password)]
        [Display(Name = "Confirm Password")]
        [Compare("Password", ErrorMessage = "Passwords do not match")]
        public string ConfirmPassword { get; set; }
    }

cshtml.cs:

public class RegisterModel : PageModel
    {

        public IActionResult OnGet()
        {
            return Page();
        }


        public Users Users { get; set; }
        [BindProperty]
        public PassWordModel passWordModel { get; set; }
   
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }


            return RedirectToPage("./Index");

        }
    }

cshtml:

<div class="container-fluid h-100 row nogap">
    <div class="card border-secondary mx-auto center col-lg-3 col-md-4 p-0" style="margin-top:100px;">
        <div class="card-header">
            Register
            <a class="float-right" asp-page="/Login">Login</a>
        </div>
        <form method="post">
            <div class="card-body text-secondary">
                <div class="form-group">
                    <label asp-for="Users.Email" class="control-label">Email</label>
                    <input type="email" asp-for="Users.Email" class="form-control">
                    <span asp-validation-for="Users.Email" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="passWordModel.Password" class="control-label"></label>
                    <input asp-for="passWordModel.Password" type="password" class="form-control">
                    <span asp-validation-for="passWordModel.Password" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="passWordModel.ConfirmPassword" class="control-label"></label>
                    <input type="password" asp-for="passWordModel.ConfirmPassword" class="form-control">
                    <span asp-validation-for="passWordModel.ConfirmPassword" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Users.Username" class="control-label"></label>
                    <input type="text" asp-for="Users.Username" class="form-control">
                    <span asp-validation-for="Users.Username" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Register" class="btn btn-primary mb-1" style="float:right" />
                </div>
            </div>
        </form>
        <div class="card-footer">
            <a>Log in with Google</a>
        </div>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

result: enter image description here

Upvotes: 1

Related Questions