when call api using ajax jQuery validation annotation not working?

Ahmed Abd El Aziz 315 Reputation points
2023-09-11T23:45:58.43+00:00

I work on asp.net MVC application I call API using ajax jQuery to prevent change URL after click submit button

from

Resignation/RequesterIndex?filenumber=103085

to

Resignation/RequesterIndex

and call ajax jQuery working success without change URL but on same time validation annotation model state not working .

so How to display validation ?

public class ResignationRequester
{
    [Required]
    [Display(Name = "Dept./ Branch: ")]
    public string Dept { get; set; }

    [Required]
    [Display(Name = "Designation: ")]
    public string Designation { get; set; }

}
controller action

public class ResignationController : Controller
    {


        public ActionResult RequesterIndex(string filenumber)
        {
            
            return View(resignationRequester);
        }
       
       
        [HttpPost]
        public ActionResult RequesterIndex(ResignationRequester resignationRequester)
        {
          
          
                if (ModelState.IsValid)
                {
                    
                  
                    try
                    {
                        Workforce.InsertToReignation(resignationRequester, (string)Session[SessionKeys.Username], (DateTime)Session[SessionKeys.LastWorkingDate], noticeperiod, (int)Session[SessionKeys.UserCode]);
                    }
                    catch (Exception ex)
                    {
                        ViewBag.errorMsg = "Create Not Done Correctly";
                    }
                    Session[SessionKeys.DirectManager] = GetEmployeeName(Convert.ToString(resignationRequester.DirectManager));
                    Session[SessionKeys.LineManager] = GetEmployeeName(Convert.ToString(resignationRequester.LineManager));
                    if (string.IsNullOrEmpty(ViewBag.errorMsg))
                    {
                        ViewBag.successMessage = "Resignation Submission form Created successfully";
                    }

                 
                }
                else
                {
                    var errors = ModelState.Select(x => x.Value.Errors)
                                            .Where(y => y.Count > 0)
                                            .ToList();
                    ViewBag.errorMsg = "Some Required Fields Not Added";
                    goto InvalidModel;
                }
            }
            else
            {
                ViewBag.errorMsg = "No Data For This File No";
            }
        InvalidModel:
            ViewBag.isPostBack = true;
                return View(resignationRequester);
     
     
    }

view ResignationRequester.cshtml

@model HR.WorkforceRequisition.Models.ResignationRequester

@{
    ViewBag.Title = "Requester Index";
}

@using (Html.BeginForm("RequesterIndex", "Resignation", FormMethod.Post, new { enctype = "multipart/form-data", @id = "ResignationApp", style = "padding-top: 50px" }))
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
    @if (!string.IsNullOrEmpty(ViewBag.errorMsg))
    {
        <div class="alert alert-danger">
            @ViewBag.errorMsg
        </div>
    }

    @if (!string.IsNullOrEmpty(ViewBag.successMessage))
    {
        <div class="alert alert-success">
            @ViewBag.successMessage
        </div>
    }

    <div class="row">
        <div class="form-group col-md-6 hover">
            <div class="col-md-5">
                @Html.LabelFor(model => model.Dept, htmlAttributes: new { @class = "control-label" })
            </div>

            <div class="col-md-7">
                @Html.EditorFor(model => model.Dept, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Dept, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group col-md-6 hover">
            <div class="col-md-5">
                @Html.LabelFor(model => model.Designation, htmlAttributes: new { @class = "control-label" })
            </div>

            <div class="col-md-7">
                @Html.EditorFor(model => model.Designation, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Designation, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>

  
    <div class="form-group">
        <div class="col-md-offset-0 col-md-12">
            <input type="submit" value="Submit" class="btn btn-success" />
        </div>
    </div>
</div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
call jQuery ajax will call action Requester Index on Resignation Controller

$("#ResignationApp").submit(function (e) {
                e.preventDefault(); // Prevent the default form submission

                var formData = $(this).serialize();
                console.log("data is" + formData)
                $.ajax({
                    type: "POST",
                    url: '@Url.Action("RequesterIndex", "Resignation")',
                   data: formData,
                    success: function (response) {
                        $("#successMessage").show();
                    },
                    error: function (error) {
                        console.error(error);
                    }
                });
            });

I do investigation about that and found issue on ajax jQuery call

e.preventDefault();

when remove it validation working but on same time URL will change

so How to make validation working and URL not changed ?

Expected result

when leave department or designation empty then it must display validation required for me

required validation error without change URL

but this not happen

if i remove e.preventdefault from jQuery it will solve issue validation

but on same time URL will change from

Resignation/RequesterIndex?filenumber=103085 to Resignation/RequesterIndex
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,331 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Lan Huang-MSFT 26,916 Reputation points Microsoft Vendor
    2023-09-12T03:57:43.4433333+00:00

    Hi @Ahmed Abd El Aziz,

    There is a problem with the RequesterIndex post part of the code you provided, and there is a problem with the position of the brackets (it may be that you accidentally pasted it wrong when pasting it).

    I modified the error and then tested it.

    User's image

    public class ResignationController : Controller
    {
        // GET: Resignation
        public ActionResult RequesterIndex(string filenumber)
        {
            ResignationRequester resignationRequester = new ResignationRequester();
            return View(resignationRequester);
        }
    
    
        [HttpPost]
        public ActionResult RequesterIndex(ResignationRequester resignationRequester)
        {
    
    
            if (ModelState.IsValid)
            {
    
    
                try
                {
                    // Workforce.InsertToReignation(resignationRequester, (string)Session[SessionKeys.Username], (DateTime)Session[SessionKeys.LastWorkingDate], noticeperiod, (int)Session[SessionKeys.UserCode]);
                }
                catch (Exception ex)
                {
                    ViewBag.errorMsg = "Create Not Done Correctly";
                }
                // Session[SessionKeys.DirectManager] = GetEmployeeName(Convert.ToString(resignationRequester.DirectManager));
                //Session[SessionKeys.LineManager] = GetEmployeeName(Convert.ToString(resignationRequester.LineManager));
                if (string.IsNullOrEmpty(ViewBag.errorMsg))
                {
                    ViewBag.successMessage = "Resignation Submission form Created successfully";
                }
    
    
    
                else
                {
                    var errors = ModelState.Select(x => x.Value.Errors)
                                            .Where(y => y.Count > 0)
                                            .ToList();
                    ViewBag.errorMsg = "Some Required Fields Not Added";
                    goto InvalidModel;
                }
    
            }
            else
            {
                ViewBag.errorMsg = "No Data For This File No";
            }
        InvalidModel:
            ViewBag.isPostBack = true;
            return View(resignationRequester);
    
    
        }
    }
    
     public class ResignationRequester
     {
         [Required]
         [Display(Name = "Dept./ Branch: ")]
         public string Dept { get; set; }
    
         [Required]
         [Display(Name = "Designation: ")]
         public string Designation { get; set; }
    
     }
    
    @{
        ViewBag.Title = "Requester Index";
    }
    
    @using (Html.BeginForm("RequesterIndex", "Resignation", FormMethod.Post, new { enctype = "multipart/form-data", @id = "ResignationApp", style = "padding-top: 50px" }))
    {
        @Html.AntiForgeryToken()
        <div class="form-horizontal">
            @if (!string.IsNullOrEmpty(ViewBag.errorMsg))
            {
                <div class="alert alert-danger">
                    @ViewBag.errorMsg
                </div>
            }
    
            @if (!string.IsNullOrEmpty(ViewBag.successMessage))
            {
                <div class="alert alert-success">
                    @ViewBag.successMessage
                </div>
            }
    
            <div class="row">
                <div class="form-group col-md-6 hover">
                    <div class="col-md-5">
                        @Html.LabelFor(model => model.Dept, htmlAttributes: new { @class = "control-label" })
                    </div>
    
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Dept, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Dept, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="form-group col-md-6 hover">
                    <div class="col-md-5">
                        @Html.LabelFor(model => model.Designation, htmlAttributes: new { @class = "control-label" })
                    </div>
    
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Designation, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Designation, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>
    
    
            <div class="form-group">
                <div class="col-md-offset-0 col-md-12">
                    <input type="submit" id="btnSubmit" value="Submit" class="btn btn-success" />
                </div>
            </div>
        </div>
    }
    
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }
    <script src="~/Scripts/jquery-3.4.1.min.js"></script>
    <script>
        $('#btnSubmit').click(function () {
            if ($("#ResignationApp").valid()) {
                $('#ResignationApp').submit();
            }
            else {
                return false;
            }
        });
        $("#ResignationApp").submit(function (e) {
            e.preventDefault(); // Prevent the default form submission
    
            var formData = $(this).serialize();
            console.log("data is" + formData)
            $.ajax({
                type: "POST",
                url: '@Url.Action("RequesterIndex", "Resignation")',
                data: formData,
                success: function (response) {
                    $("#successMessage").show();
                },
                error: function (error) {
                    console.error(error);
                }
            });
    
        });
    </script>
    
    
    

    10

    Best regards,
    Lan Huang


    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.

    0 comments No comments

  2. Bruce (SqlWork.com) 58,441 Reputation points
    2023-09-12T18:05:58.5133333+00:00

    the client validation is done by the jquery validation plugin:

    https://jqueryvalidation.org

    the plug hooks up to form submit. as your code is cancelling the submit, it will not be called. you just call the form validation yourself:

    $("#ResignationApp").submit(function (e) {
                    e.preventDefault(); // Prevent the default form submission
                    if (!$(this).validate().form())
                        return;
                    ...   
    

    note: if you have additional server validation, you will need to display the results yourself. look at the unobtrusive source code to how this is done.

    https://github.com/aspnet/jquery-validation-unobtrusive

    also if you replace the form elements via javascript, you will have re-attach the validation rules. this is done by calling parse of the unobtrusive library.

    0 comments No comments