Search code examples
asp.net-mvcalertdata-annotations

How to hide alert box when validation is on server side with Data Annotation on page load


I created a simple login page on mvc where the user must be notified when not entering password or username, using data annotation as following.

 [Required(ErrorMessage = "password needed")]
    public string password { get; set; }
    [Required(ErrorMessage = "user name needed")]
    public string username{ get; set; }

In the controller I'm testing with hard coded values as follwoing:

 public ActionResult Login2(Login login)
    {
        string username = login.username;    
        string password = login.password;
        if (ModelState.IsValid)
        {              
            if (username == "100000" && password == "password")
            {
                return RedirectToAction("Index", "Home");
            }               
           else{
           return View();
           }
        }
        return View();

In the viwe, I verify with validation message as below:

         <label class="form-label" for="contactPhone">
                          username
                        </label>
                        @Html.EditorFor(model => model.CVR, new { 
           htmlAttributes = new { @class = "form-input", PlaceHolder = 
               "username", maxlength = "10", Type="HtmlInputFile", 
                    id="username" , value=""} })
                        <br>
                        @Html.ValidationMessageFor(model => 
                  model.username, "", new { @class = "alert alert-error" })

                        <label class="form-label" for="contactPhone">
                            p<ssword
                        </label>
                        @Html.EditorFor(model => model.password, 
          "Password", new { htmlAttributes = new { @class = "form- 
           input", PlaceHolder = "password" } })
                        <br>
                        @Html.ValidationMessageFor(model => 
               model.password, "", new { @class = "alert alert-error" })
                    <button class="button button-primary button-active" 
                   id="danger" type="submit">Login</button>

The problem is that the alert box is displayed on the page load (empty). Once the submit button without filling the fields the error message is displayed. My questions are as follwoing: 1- how to hide the red alert box when loading the login page? 2- how to add more restrections for validating the username and password. for example:

  1. how to validate the correct password? and display the error message in the alert box?
  2. how to validate the correct username?and display the error in the alert box?

Solution

  • The standard way of doing this in MVC is to add all your validations to your model:

    public class LoginViewModel
    {
        [Required(ErrorMessage = "password needed")]
        public string Email { get; set; }
    
        [Required(ErrorMessage = "user name needed")]
        public string Password { get; set; }
    }
    

    Then in your Controller, you would check if the model is valid:

    public ActionResult Login2(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model); // <-- return invalid model to the same view (Login2) so  user can fix it        
        }
    
        // code for valid model...
    }
    

    And display the error message in the view like:

    @using (Html.BeginForm("Login2", "Account", FormMethod.Post, new { role = "form" }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form login-form">
            <div class="form-group">
                @Html.LabelFor(m => m.username, new { @class = "" })
                @Html.TextBoxFor(m => m.username, new { @class = "form-control" })
                @Html.ValidationMessageFor(m => m.username, "", new { @class = "text-danger" })
            </div>
    
            <div class="form-group">
                @Html.LabelFor(m => m.password, new { @class = "" })
                Html.PasswordFor(m => m.password, new { @class = "form-control" })
                @Html.ValidationMessageFor(m => m.password, "", new { @class = "text-danger" })
            </div>
        </div>
    }
    

    See this answer for customizing password validation rules.