skip to Main Content

I’m working on ASP.NET Core MVC application, I have a registration page as below, I want to return View with errors when the model state is false :

@model WebApplication2PROP.Entities.UserRegister
@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<section id="RegSection">
    <div class="container">
        <div class="row justify-content-center align-items-center">
            <div class="col-lg-6 col-md-6 col-sm-12 justify-content-center text-start ">


                    <span asp-validation-for="FirstName" class="Validation"></span>
                    <br />
                    <label for="FirstName" class="form-label">First Name</label>
                    <input type="text" id="FirstName" class="form-control" value="@Model.FirstName" name="FirstName" />
                    <br />

                    <span asp-validation-for="LastName" class="Validation"></span>
                    <br />
                    <label for="LastName" class="form-label">Last Name</label>
                    <input type="text" id="LastName" class="form-control" value="@Model.LastName" name="LastName"/>

                    <br />

                    <span asp-validation-for="UserName" class="Validation"></span>
                    <br />
                    <label for="UserName" class="form-label">User name</label>
                    <input type="text" id="UserName" class="form-control" value="@Model.UserName" name="UserName" />

                    <br />
                    <span asp-validation-for="Phonenumber" class="Validation"></span>
                    <br />
                    <label for="PhoneNumber" class="form-label">PhoneNumber</label>
                    <input type="text" id="PhoneNumber" class="form-control" value="@Model.Phonenumber" name="Phonenumber"/>

                    <br />
                    <span asp-validation-for="Password" class="Validation"></span>
                    <br />
                    <label for="Password" class="form-label">Password</label>
                    <input type="password" id="Password" class="form-control" value="@Model.Password" name="Password" />

                    <br />
                    <span asp-validation-for="ConfirmPassword" class="Validation"></span>
                     <br />
                    <label for="ConfirmPassword" class="form-label">Confirm Password</label>
                    <input type="password" id="ConfirmPassword" class="form-control" value="@Model.ConfirmPassword" name="ConfirmPassword" />


                    <div class="text-center"> <button class="btn text-center RegBut" id="RegBut">Register</button></div>
                    <div class="text-center">
                        Already have an account? @Html.ActionLink("Login","LoginPage","Home",null,new {@class ="btn RegBut"})
                    </div>


                
                 
            </div>
            
        </div>
    </div>
</section>

controller:

[HttpPost]
        public async Task <IActionResult>  SubmitLogin([FromBody]LogIn user)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(new { data = false });
                }
                else
                {
                    return Ok(new { data = true });
                }
                await operations.Login(user);
                return RedirectToAction("MainPage","Home");
            }
            catch (Exception ex) 
            {
                ModelState.AddModelError(nameof(user.UserName), ex.Message);
                return View("HomePage", user);
            }
        }

Now, I want to send the data using ajax:

 $("#RegBut").click(function () {
         //   alert("clicked")
            var FirstName=$("#FirstName").val();
            var LastName = $("#LastName").val();
            var UserName = $("#UserName").val();
            var PhoneNumber = $("#PhoneNumber").val();
            var Password = $("#Password").val();
            var ConfirmPassword = $("#ConfirmPassword").val();
            var Data = { FirstName: FirstName, LastName: LastName, UserName: UserName, PhoneNumber: PhoneNumber, Password: Password, ConfirmPassword: ConfirmPassword }
            $.ajax({
                type: "POST",
                url: "/Home/SubmitRegister",
                contentType: "application/json",
                data: JSON.stringify(Data),
                success:function(data)
                {
                    if (data.success)
                    {
                     // Registration was successful, redirect to MainPage
                      window.location.href = '/Home/MainPage';
                     }
                 else 
                 {
                     // Registration failed, update UI with validation errors
                     alert("Data is not success");
                     console.log(data)
                  }
                 },
                error: function (data) 
                {
                    console.log(data);
                }

            });
        });

**
The issue is, when the user submit the data to the controller, if ModelState is false, how to redirect to the above view and make each validation error above related input field ?**

I tried to return view as below:

[HttpPost]
        public async Task <IActionResult> SubmitLogin([FromBody]LogIn user)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return View("Register",user);
                }
                else
                {
                    return Ok(new { data = true });
                }
                await operations.Login(user);
                return RedirectToAction("MainPage","Home");
            }
            catch (Exception ex) 
            {
                ModelState.AddModelError(nameof(user.UserName), ex.Message);
                return View("HomePage", user);
            }
        }

but it does not work, it returns the HTML to the ajax.

2

Answers


  1. Here the problem is you are using jQuery Ajax to call your controller method. The problem here is that whenever any validation error occurs you are sending a full view so it renders the whole HTML in your response. Just remember you are using jQuery Ajax so instead of returning a view you should return a bad request like the following

    if (!ModelState.IsValid)
    {
       return BadRequest(ModelState);
    }
    

    Now you will get all the validation messages and same way you can do this with an exception here.

            catch (Exception ex) 
            {
                ModelState.AddModelError(nameof(user.UserName), ex.Message);
                return BadRequest(ModelState);
            }
    
    Login or Signup to reply.
  2. I’m working on ASP.NET Core MVC application, I have a registration
    page as below, I want to return View with errors when the model state
    is false :

    The issue with your current approach is that returning the view directly as a response to the AJAX request won’t work. AJAX expects a JSON response, not HTML.

    Here’s the example how you can resolve the issue.

    Modify your server response:

    if (!ModelState.IsValid)
    {
        var errors = new List<object>();
        foreach (var key in ModelState.Keys)
        {
            foreach (var error in ModelState[key].Errors)
            {
                errors.Add(new { field = key, message = error.ErrorMessage });
            }
        }
        return Json(new { success = false, errors = errors });
    }
    

    Note: Point to keep in mind, you need to handle it on the client side. Instead of returning a view directly from the controller, you can return a JSON object containing the validation errors. What exactly I’m doing here.

    Modify your ajax response:

    if (!data.success) {
        for (var error of data.errors) {
            console.log(error.field + "-" + error.message);
            var inputElement = $("#" + error.field);
            console.log(inputElement);
            inputElement.addClass("is-invalid");
            inputElement.siblings(".Validation[name='" + error.field + "']").html(error.message);
        }
    }
    

    Modify your validation span Name property:

     <span class="Validation" name="FirstName"></span>
    

    Note: Same goes for other spans as well.

    Output:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search