Search code examples
jqueryajaxasp.net-core

Why the validation messages not appear when using Ajax with ASP.NET Core application


I am using Ajax with an ASP.NET Core application, but when I submit the form, the validation messages of the inputs do not appear with the invalid inputs.

When I stop using AJAX, the validation messages start to appear. How I can solve that?

This the code of the ASP.NET Core method:

[HttpPost]
public async Task<IActionResult> Index([FromBody] AddTaskViewModel model)
{
    try
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
    }
    catch()
    {  }
}

And this the view model class:

public class AddTaskViewModel
{
    public long ID { get; set; } = 11;

    [Required(ErrorMessage ="Enter Task Name")]
    public string TaskName { get; set; }

    [Required(ErrorMessage ="Enter Task Description")]
    public string TaskDescription { get; set; }

    public string Notes { get; set; }
}

This the view markup:

<div class="row" id="AForm">
    <div class="col-md-12">
        <div class="card m-b-20">
            <div class="card-header">
                <h3 class="card-title">Add Task</h3>
            </div>
            <div class="card-body">
                <form id="AddTaskForm" asp-controller="ManageTasks" asp-action="Index">
                    <div class="form-row">
                        <div class="form-group col-md-6">
                            <label asp-for="TaskName" class="col-form-label">Task Name</label>
                            <input asp-for="TaskName" type="text" id="inputTaskName" class="form-control">
                            <span asp-validation-for="TaskName" class="text-danger"></span>
                        </div>
                        <div class="form-group col-md-6">
                            <label asp-for="TaskDescription" class="col-form-label">Task Desc</label>
                            <input type="text" class="form-control" asp-for="TaskDescription" id="inputDesc">
                            <span asp-validation-for="TaskDescription" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-12">
                            <label asp-for="Notes" class="col-form-label">Notes</label>
                            <textarea class="form-control" asp-for="Notes" id="inputTaskNote" rows="4" ></textarea>
                        </div>
                    </div>
                    <button type="submit" class="btn btn-primary ">Add Task</button>
                </form>
            </div>
        </div>
    </div>
</div>

This is the Ajax code:

$("#AddTaskForm").submit(function (event) {
    event.preventDefault();
    var TaskName = $("#inputTaskName").val();
    var TaskDesc = $("#inputDesc").val();
    var Id = "1";
    var TaskNote = $("#inputTaskNote").val();

    var data = {
                    ID: Id,
                    TaskName: TaskName ,
                    TaskDescription: TaskDesc ,
                    Notes: TaskNote
                };

    $.ajax({type: 'POST',
            url: '@Url.Action("Index","ManageTasks")',
            data: JSON.stringify(data),
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function (result, status, xhr) {
                console.log(result);
            }
          })
   })

Solution

  • When you using the ajax, the standard ASP.NET Core validation mechanism doesn't automatically render the validation messages back to the view.

    To address this, you need to handle the validation response manually in your AJAX success callback and update the view.

    More details, you could refer to below example:

    My home controller:

        [HttpPost]
        public async Task<IActionResult> Index([FromBody] AddTaskViewModel model)
        {
    
            if (!ModelState.IsValid)
            {
                var errors = ModelState.Where(x => x.Value.Errors.Any())
                                       .ToDictionary(x => x.Key, x => x.Value.Errors.First().ErrorMessage);
                return Json(new { success = false, errors });
            }
    
            // Process valid model and return success
            return Json(new { success = true });
    
    
        }
    

    View with jquery codes:

    @{
        ViewData["Title"] = "Home Page";
    }
    
    @model AddTaskViewModel
     
    
    <div class="row" id="AForm">
        <div class="col-md-12">
            <div class="card m-b-20">
                <div class="card-header">
                    <h3 class="card-title">Add Task</h3>
                </div>
                <div class="card-body">
                    <form id="AddTaskForm" asp-controller="ManageTasks" asp-action="Index">
                        <div class="form-row">
                            <div class="form-group col-md-6">
                                <label asp-for="TaskName" class="col-form-label">Task Name</label>
                                <input asp-for="TaskName" type="text" id="inputTaskName" class="form-control">
                                <span id="TaskName-error" class="text-danger"></span> <!-- Updated span ID -->
                            </div>
                            <div class="form-group col-md-6">
                                <label asp-for="TaskDescription" class="col-form-label">Task Desc</label>
                                <input type="text" class="form-control" asp-for="TaskDescription" id="inputDesc">
                                <span id="TaskDescription-error" class="text-danger"></span> <!-- Updated span ID -->
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group col-md-12">
                                <label asp-for="Notes" class="col-form-label">Notes</label>
                                <textarea class="form-control" asp-for="Notes" id="inputTaskNote" rows="4"></textarea>
                            </div>
                        </div>
                        <button type="submit" class="btn btn-primary">Add Task</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
    
    @section Scripts{
    
    <script>
            // $("#AddTaskForm").submit(function (event) {
            //     event.preventDefault();
            //     var TaskName = $("#inputTaskName").val();
            //     var TaskDesc = $("#inputDesc").val();
            //     var Id = "1";
            //     var TaskNote = $("#inputTaskNote").val();
    
            //     var data = {
            //         ID: Id,
            //         TaskName: TaskName,
            //         TaskDescription: TaskDesc,
            //         Notes: TaskNote
            //     };
    
            //     $.ajax({
            //         type: 'POST',
            //         url: '@Url.Action("Index", "ManageTasks")',
            //         data: JSON.stringify(data),
            //         contentType: "application/json; charset=utf-8",
            //         dataType: 'json',
            //         success: function (result, status, xhr) {
            //             console.log(result);
            //         }
            //     })
            // })
    
            $("#AddTaskForm").submit(function (event) {
                event.preventDefault();
                var TaskName = $("#inputTaskName").val();
                var TaskDesc = $("#inputDesc").val();
                var Id = "1";
                var TaskNote = $("#inputTaskNote").val();
    
                var data = {
                    ID: Id,
                    TaskName: TaskName,
                    TaskDescription: TaskDesc,
                    Notes: TaskNote
                };
    
                $.ajax({
                    type: 'POST',
                    url: '@Url.Action("Index", "Home")',
                    data: JSON.stringify(data),
                    contentType: "application/json; charset=utf-8",
                    dataType: 'json',
                    success: function (result, status, xhr) {
                        if (result.success) {
                            // Handle success, maybe redirect or show a success message
                            console.log("Task added successfully.");
                        } else {
                            // Handle validation errors
                            debugger;
                            $.each(result.errors, function (key, value) {
                                // Display validation messages in the appropriate spans
                                $("#" + key + "-error").text(value);
                            });
                        }
                    }
                });
            });
    </script>
    }
    

    Result:

    enter image description here