This is a migrated thread and some comments may be shown as answers.

Razor Pages - Unobtrusive Validation Issue

4 Answers 1447 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Arturs
Top achievements
Rank 1
Arturs asked on 12 Mar 2020, 10:19 AM

Hey,

So I've been using the asp.net core kendo and it is great but I cannot seem to get over one hurdle and that is the validation.

I have extended the kendo validation to include remote validation to check if a field name exists in the database already, that all works fine but the problem currently is that if I include the jQuery validation and jQuery unobtrusive validation into my scripts I would get 404 errors every time I type something into the text box (because the remote url passed down is different on unobtrusive than on kendo validation). I have attached an image of the 404 error I am getting.

But if I remove jQuery validation and jQuery unobtrusive I get no errors but because of the nature of razor pages the kendo remote validation does not register to the model and so even if the remote validation failed, the field is updated/added.

app.js

"use strict";
 
import gridFunctions from "./js/gridFunctions";
 
// Top level packages that need to be initiated first
import $ from "../node_modules/jquery/dist/jquery";
window.jQuery = $;
window.$ = $;
gridFunctions();
 
// Scss
import "./scss/app.scss";
 
// Add all kendo
import "@progress/kendo-ui";
import "@progress/kendo-ui/js/kendo.aspnetmvc";
import "@popperjs/core";
 
// Add jquery validation
import "jquery-validation/dist/jquery.validate";
import "jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive";
 
// Add boostrap js
import "@popperjs/core/dist/cjs/popper";
import "bootstrap/dist/js/bootstrap.bundle";
 
// Add Font Awesome
import "@fortawesome/fontawesome-free/js/all";
 
$.validator.setDefaults({
    ignore: ""
});

 

Edit.cshtml

 <form method="post">
    <input type="hidden" asp-for="@Model.SystemRole.SystemRoleId" />
 
    @* Inputs *@
    <div class="row">
        <div class="col-sm-3">
            <div class="input-outer">
                <label asp-for="@Model.SystemRole.SystemRoleDesc" class="required"></label>
                <input asp-for="@Model.SystemRole.SystemRoleDesc"
                       data-val-remote-additionalfields="SystemRoleDesc"
                       data-val-remote-url="CheckSystemRoleDescExists"
                       class="k-textbox" />
                <span asp-validation-for="@Model.SystemRole.SystemRoleDesc"></span>
            </div>
 
            <div class="input-outer">
                <label asp-for="@Model.SystemRole.SystemRoleRef" class="required"></label>
                <input asp-for="@Model.SystemRole.SystemRoleRef"
                       data-val-remote-additionalfields="SystemRoleRef"
                       data-val-remote-url="CheckSystemRoleRefExists"
                       class="k-textbox" />
                <span asp-validation-for="@Model.SystemRole.SystemRoleRef"></span>
            </div>
 
            <div class="input-outer">
                <label asp-for="@Model.SystemRole.IsDeleted"></label>
                <input asp-for="@Model.SystemRole.IsDeleted" type="checkbox" data-validate="false" class="k-checkbox">
                <span asp-validation-for="@Model.SystemRole.IsDeleted"></span>
            </div>
        </div>
        <div class="col-sm-3"></div>
        <div class="col-sm-3"></div>
        <div class="col-sm-3"></div>
    </div>
 
    <hr />
 
    @* Buttons *@
 
    <input type="submit" value="Update" class="btn btn-primary" />
 
</form>
 

 

Any help is really appreciated! 

Thank you.

4 Answers, 1 is accepted

Sort by
0
Aleksandar
Telerik team
answered on 17 Mar 2020, 09:44 AM

Hello Arturs,

To use the Kendo validator it needs to be added to the Form that needs to be validated:

<form method="post" kendo-validator="true" id="myform">
...
</form>

Then validate the form on submit:

var validator = $("#myform").data("kendoValidator");

        $("form").submit(function (event) {
            event.preventDefault();
            validator.validate()
        });

In regards to the remote validation, I would assume the following guideline was followed - Implement Remote Validation. In this scenario update the remote url to the page handler performing the validation

<form method="post" kendo-validator="true" id="myform">
    <input asp-for="Email" />
    <span asp-validation-for="Email" data-val-remote-url="@Url.PageLink("Index","CheckEmail")"></span><br>
    <input type="submit" />
</form>
 Update the ajax request so that the input elements are sent as FromData:


var postData = new FormData(document.getElementById("myform"));
$.ajax({
    url: url,
    type: "POST",
    data: postData,
    cache: false,
    processData: false,
    contentType: false,
    dataType: "json",
    success: function (data) {
      ...
    },
    error: function (data) {
      ...
    }
});

The Page handler would perform the validation and return an error message if the validation fails:

public JsonResult OnPostCheckEmail()
        {
            var existingEmails = new[] { "jane@test.com", "claire@test.com", "dave@test.com" };
            var valid = !existingEmails.Contains(Email);
            if (!valid)
            {
                return new JsonResult("This Email already exists");
            }
            return new JsonResult(valid);
        }

Finally, the property would be decorated with the BindProperty attribute and PageRemote attribute:

        [PageRemote(
            AdditionalFields = "__RequestVerificationToken",
            HttpMethod = "Post",
            PageHandler = "CheckEmail"
        )]
        [BindProperty]
        [Required]
        public string Email { get; set; }

Upon submission of an existing email the remote validation would be triggered:

Attached is a sample ASP.NET Core solution with the above implemented. I hope this helps implement the desired functionality in the application. Let me know if you have additional questions.

Regards,
Aleksandar
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
Arturs
Top achievements
Rank 1
answered on 20 Mar 2020, 03:26 PM

Hi Aleksandar

Thanks for your help, I do not have issue with setting up remote validation, all of that is working fine for me. My issue is that when remote validation is passed and I click the submit button (and because of event.preventDefault()) nothing gets submitted to the database and so no rows are saved.

This has been my big roadblock and I've scoured every corner of the next looking for a solution. 

Thanks

0
Arturs
Top achievements
Rank 1
answered on 23 Mar 2020, 03:07 PM

God, I am getting so frustrated with this validation crap.

 

Look, I am able to remotely validate a value that checks the database and returns an error message which then gets appended to the data-val-remote attribute and the error is shown.

BUT!!!!!!!!!!!!!!!!!!!

I am still able to save because the validator.validate() always returns true!!!!

SO the event.preventDefault() is not triggered even though the remote validation has failed!

What the hell am I doing wrong here...................

0
Aleksandar
Telerik team
answered on 25 Mar 2020, 12:59 PM

Hi Arturs,

I have updated the initially provided example and made the following modifications so that when the form is valid it will be submitted to the respective handler. The first modification you could make is changing the input type of the form from "submit" to "button" and handle the button click event to validate the form:

<form method="post" asp-page-handler="FormSubmit" kendo-validator="true" id="myform">
   ...
    <input id="btn" type="button" value="Submit" />
</form>


$("#btn").click(function (event) {
            event.preventDefault();
            var isFormValid = validator.validate();
            if (isFormValid) {
                $('form').submit();
            } 
        });

I further updated the remote validation logic and the server would return a bad request in case the validation is not successful and the respective validation message will be displayed: 

public ActionResult OnPostCheckEmail()
        {
            var existingEmails = new[] { "jane@test.com", "claire@test.com", "dave@test.com" };
            var valid = !existingEmails.Contains(Email);
            if (!valid)
            {
                return new StatusCodeResult(400);
            }
            return new JsonResult(new { Success = true });
        }


$("#myform").kendoValidator({
        validateOnBlur: true,
        messages: {
            email: "This Email already exists",
        },
        rules: {
            email: function (input) {
                return inputRule(input, "Email");
            }
        }
    });

The inputRule function will check the validation state of the input and trigger remote validation. Check the attached updated project for further details.

I hope this helps. Let me know if you have additional questions.

Regards,
Aleksandar
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
General Discussions
Asked by
Arturs
Top achievements
Rank 1
Answers by
Aleksandar
Telerik team
Arturs
Top achievements
Rank 1
Share this question
or