Validation of the input fields is not working in Asp. Net Core 6.0 MVC

Sherpa 306 Reputation points
2024-08-26T02:33:03.2266667+00:00

I am working with Asp.Net Core 6.0 MVC. The Year field in the model is required. When the page is processed without entering the year, the Model.IsValid = false as expected in the controller. However the error message, "Year is required" is not displayed. Essentially the validation doesn't work. When I inspected the Year input control in Chrome, the validation code seemed to be present. I have enclosed the image showing the inspected input control.YearControl

Controller Code:

[HttpPost]
public async Task<string> ProcessReport(ReportsConfigurationVM reportsConfigurationVM)
{
    
    if (ModelState.IsValid)
    {
        List<RiskByYearTest> myList = new List<RiskByYearTest>();
    	RiskByYearTest r1 = new RiskByYearTest();
    	r1.CustomerNumber = "4549601";
    	r1.CustomerStatus = "Active";
    	r1.StartYear = "2022";
    	RiskByYearTest r2 = new RiskByYearTest();
    	r2.CustomerNumber = "4549602";
    	r2.CustomerStatus = "Closed";
    	r2.StartYear = "2023";
    	myList.Add(r1);
    	myList.Add(r2);
    	return JsonConvert.SerializeObject(myList);
    }
    return string.Empty; 
    
}

Model:
public string? ProgramManagerID { get; set; }
public string? Date1 { get; set; }
public string? Date2 { get; set; }
[Required(ErrorMessage = "Year is required")]        
public string? Year { get; set; }
public int UserID { get; set; }


Index.cshtml:
@model ViewModels.ReportsConfigurationVM
<div class="display-area ">
   
    <div style="padding-top: 10px; padding-left: 5px">
        <form id="reportForm" method="post">
            
            <div asp-validation-summary="All" class="text-danger" style="text-align:left"></div>
            <div class="card" style="width: 18rem;height: auto;width:800px ">
                <div class="card-header">
                    Available Reports
                </div>
                <div class="form-floating register-input">
                    <!-- input  -->
                    <input id="Year" placeholder="editlabel" asp-for="Year" class="form-control" />
                    <!-- label  -->
                    <label>Enter Year</label>
                    <!-- required -->
                    <span asp-validation-for="Year" class="text-danger"></span>
                </div>
            
        </div>
    </div>
   </form>
   <div style="padding-top: 20px; padding-bottom:20px">
    <button class="btn btn-lg btn-primary" onclick="javascript:runReport();">Run Report</button>
    <button id="clear" class="btn btn-lg btn-secondary">Clear Filters</button>
   </div>

@section Scripts {
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
    @{
            <partial name="_ValidationScriptsPartial" />
            <partial name="_DataTableCDN" />
    }
<script>
    
    function runReport() {
        
        var reportData;
                 
        var dataTableOptions = {
            "paging": true,
            "lengthChange": false,
            "searching": false,
            "ordering": true,
            "info": true,
            "autoWidth": false,
            "responsive": true,
            "columnDefs": "",
            
            "ajax": {
                url: "/Reports/ProcessReport",
                type: "POST",
                data: reportData,                    
                "error": function (e) {
                    console.log(e);
                },
                "dataSrc": '',
                
            },
            "columns": [
                { "data": "CustomerNumber", "name": "CustomerNumber", "autoWidth": true},
                { "data": "CustomerStatus", "name": "CustomerStatus", "autoWidth": true },
                { "data": "StartYear", "name": "StartYear", "autoWidth": true }
            ],
        }

        
        reportData = $('#reportForm').serializeArray();
        var myDataTable = $('#riskReport').DataTable(dataTableOptions);
        
    }
}
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,504 questions
0 comments No comments
{count} votes

Accepted answer
  1. Ping Ni-MSFT 4,085 Reputation points Microsoft Vendor
    2024-08-26T06:52:47.98+00:00

    Hi @Sherpa

    For your scenario, I think ensure Client-Side Validation is Set Up by including the validation js reference(jquery.validate.unobtrusive.min.js and jquery.validate.min.js) which is enough:

    <!-- Add these in your layout or specific view -->
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
    

    And modify your js function:

    function runReport() {     
        var reportData;
        var form = $('#reportForm');
        // Trigger client-side validation
        if (!form.valid()) {
            return; 
        }
        var dataTableOptions = {
            "paging": true,
            "lengthChange": false,
            "searching": false,
            "ordering": true,
            "info": true,
            "autoWidth": false,
            "responsive": true,
            "columnDefs": "",
            "ajax": {
                url: "/eGrantsReports/ProcessReport",
                type: "POST",
                data: reportData,
                "error": function (e) {
                    alert(e)
                },
                "dataSrc": function (d) {
                    console.log(d);
                    return d;
                }
            },
            "columns": [
                { "data": "customerNumber", "name": "CustomerNumber", "autoWidth": true },
                { "data": "customerStatus", "name": "CustomerStatus", "autoWidth": true },
                { "data": "startYear", "name": "StartYear", "autoWidth": true }
            ]
        }
         reportData = $('#reportForm').serializeArray();
        var myDataTable = $('#riskReport').DataTable(dataTableOptions);
    }
    </script>
    }
    

    If the client-side validation is somehow bypassed or there are additional server-side validation rules, the controller returns a JSON object with errors. These errors are then displayed by dynamically updating the DOM using jQuery:

    @model ReportsConfigurationVM
    <div>
        <div style="padding-top: 10px; padding-left: 5px">
            <form id="reportForm" method="post">
                <div asp-validation-summary="All" class="text-danger" style="text-align:left"></div>
                <div class="card" style="width: 18rem;height: auto;width:800px ">
                    <div class="card-header">
                        Available Reports
                    </div>
                    <div class="form-floating register-input">
                        <!-- input  -->
                        <input id="Year" placeholder="editlabel" asp-for="Year" class="form-control" />
                        <!-- label  -->
                        <label>Enter Year</label>
                        <!-- Required validation message span -->                    
                        <span asp-validation-for="Year" class="text-danger"></span>
                    </div>
                </div>
            </form>
        </div>
        <div style="padding-top: 20px; padding-bottom:20px">
            <button class="btn btn-lg btn-primary" onclick="javascript:runReport();">Run Report</button>
            <button id="clear" class="btn btn-lg btn-secondary">Clear Filters</button>
        </div>
        <!-- Server side validation message  -->
        <div class="text-danger" id="errorMessages" style="display:none;"></div>
        <div>
            <table class="table table-bordered table-striped" id="riskReport">
                <thead class="bg-dark text-white">
                    <tr>
                        <th>CustomerNumber</th>
                        <th>CustomerStatus</th>
                        <th>StartDate</th>
                    </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
    </div>
    @section Scripts {       
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
        <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
        <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
        <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
    <script>
        function runReport() {     
            var reportData;
            var form = $('#reportForm');
            // Trigger client-side validation
            if (!form.valid()) {
                return; // If the form is invalid, prevent the AJAX call
            }   
            $.ajax({
                url: "/eGrantsReports/ProcessReport",
                type: "POST",
                data: form.serialize(),
                success: function (response) {
                    if (response.success) {
                        // Handle successful response
                        $('#riskReport').DataTable({
                            data: response.data,
                            columns: [
                                { data: "customerNumber" },
                                { data: "customerStatus" },
                                { data: "startYear" }
                            ],
                            destroy: true // Reinitialize DataTable
                        });
                        $('#errorMessages').hide(); // Hide previous errors if any
                    } else {
                        // Display server-side validation errors
                        var errorList = response.errors.map(error => `<li>${error}</li>`).join('');
                        $('#errorMessages').html(`<ul>${errorList}</ul>`).show();
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log('AJAX call failed:', textStatus, errorThrown);
                }
            });   
        }
    </script>
    }
    

    Backend code:

    [HttpPost]
    public async Task<JsonResult> ProcessReport(ReportsConfigurationVM reportsConfigurationVM)
    {
        if (ModelState.IsValid)
        {
            List<RiskByYearTest> myList = new List<RiskByYearTest>();
            RiskByYearTest r1 = new RiskByYearTest();
            r1.CustomerNumber = "4549601";
            r1.CustomerStatus = "Active";
            r1.StartYear = "2022";
            RiskByYearTest r2 = new RiskByYearTest();
            r2.CustomerNumber = "4549602";
            r2.CustomerStatus = "Closed";
            r2.StartYear = "2023";
            myList.Add(r1);
            myList.Add(r2);
            return Json(new { success = true, data = myList });
        }
        var errors = ModelState.Values.SelectMany(v => v.Errors)
                                    .Select(e => e.ErrorMessage)
                                    .ToList();
        return Json(new { success = false, errors });
    }
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Rena

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.