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

Remote Validation Unobtrusive using Razor Method

15 Answers 456 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Yassen
Top achievements
Rank 1
Yassen asked on 21 Feb 2017, 12:34 PM

Dear All,

I have just downloaded the asp.net MVC product.

I started with the validation using DataAnnotation attributes, which works fine for client-side validation on the UI.

I then searched for implementation of server-side validation attribute for DataAnnotation where I found the [Remote] attribute that allow to call methods on the controller, looks pretty good.

I started with the following at the Controller:

public JsonResult IsValidName(string coin_name_2)
        {
            bool found = db.IGL_coin.Any(name => name.coin_name_2 == coin_name_2);
            if (!found)
            {
                return Json(true, JsonRequestBehavior.AllowGet);
            }
            return Json(false, JsonRequestBehavior.AllowGet);
        }

 

Then I decorate my model (IGL_coin) with MetaData class that holds the validation as follows:

// Metadata defenitions
public class CoinMetadata
    {
        public int coin_id { get; set; }
 
        public string coin_name_1 { get; set; }
 
        [Required(ErrorMessageResourceType = typeof(Errors), ErrorMessageResourceName = "NameReq")]
        [Display(Name = "CoinName", ResourceType = typeof(ScreenRes))]
        [Remote("IsValidName", "Coin", ErrorMessageResourceType = typeof(Errors), ErrorMessageResourceName = "NameDuplicate")]
        public string coin_name_2 { get; set; }
 
        [Display(Name = "Rate", ResourceType = typeof(ScreenRes))]
        [Required(ErrorMessageResourceType = typeof(Errors), ErrorMessageResourceName = "RateReq")]
        [Range(0.00001,100000, ErrorMessageResourceType=typeof(Errors), ErrorMessageResourceName="RateInvalid")]
        public decimal coin_rate { get; set; }
    }
 
// Partial Classes defenitions
[MetadataType(typeof(CoinMetadata))]
public partial class IGL_coin
{}

 

Then my CoinCustomEditor partial view has the following markup to show the details:

<div style="margin: 5px 15px 5px 15px; height: auto; width: 350px">
    @using (Html.BeginForm())
     {
        @Html.AntiForgeryToken()
 
        @Html.HiddenFor(model => model.coin_id)
        @Html.ValidationSummary()
        <ul id="fieldlist">
            <li>
                @Html.LabelFor(model => model.coin_name_2)
                @Html.TextBoxFor(model => model.coin_name_2)
                @*@Html.Kendo().MaskedTextBoxFor(model => model.coin_name_2).Name("coin_name_2").HtmlAttributes(new { style = "width: 100%;" })*@
                @Html.ValidationMessageFor(model => model.coin_name_2)
 
            </li>
            <li>
                @Html.LabelFor(model => model.coin_rate)
                @Html.Kendo().TextBoxFor(model => model.coin_rate).Name("coin_rate").HtmlAttributes(new { style = "width: 100%;" })
                @Html.ValidationMessageFor(model => model.coin_rate)
            </li>
        </ul>
     }
</div>
@Scripts.Render("~/bundles/jqueryval")

 

This partial view is called from the add/edit action on the grid using GridEditMode.PopUp and .TemplateName("CoinCustomEditor")).

The problem is that the remote attribute calls the method IsValidName correctly as shown by fiddler (see attached file).

The result in the Partial view shows the red border around the TextBoxFor but the error message is not shown.

Just in case this is the jqueryval scripts loaded by partial : @Scripts.Render("~/bundles/jqueryval"), which are defined at the _Layout as follows:

<head>
    <title>@ViewBag.Title - My App</title>
 
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/kendo")
 
    @Styles.Render("~/Content/kendo/css")
     
    <link href="@Url.Content("~/Content/kendo/kendo.common.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/kendo.mobile.all.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/kendo.default.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/kendo.dataviz.default.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/kendo.rtl.min.css")" rel="stylesheet" type="text/css" />
 
    <script src="@Url.Content("~/Scripts/kendo/jquery.min.js")"></script>
 
    <script src="@Url.Content("~/Scripts/kendo/angular.min.js")"></script>
    <script src="@Url.Content("~/Scripts/kendo/jszip.min.js")"></script>
    <script src="@Url.Content("~/Scripts/kendo/kendo.all.min.js")"></script>
    <script src="@Url.Content("~/Scripts/kendo/kendo.aspnetmvc.min.js")"></script>
</head>

 

and also the BundleConfig definitions:

public class BundleConfig
{
    // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));
 
        //bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include("~/Scripts/jquery.validate*"));
        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate.min.js",
                    "~/Scripts/jquery.validate.unobtrusive.js"));
 
        // Use the development version of Modernizr to develop with and learn from. Then, when you're
        // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
        bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));
 
        bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                    "~/Scripts/bootstrap.js",
                    "~/Scripts/respond.js"));
 
        //bundles.Add(new StyleBundle("~/Content/css").Include(
        //          "~/Content/bootstrap.css",
        //          "~/Content/Site.css"));
 
        bundles.Add(new ScriptBundle("~/bundles/kendo").Include(
                 "~/Scripts/kendo/2016.2.504/kendo.all.min.js",
            // "~/Scripts/kendo/kendo.timezones.min.js", // uncomment if using the Scheduler
                 "~/Scripts/kendo/2016.2.504/kendo.aspnetmvc.min.js"));
 
        //bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
        //       "~/Content/kendo/2016.2.504/kendo.common-bootstrap.min.css",
        //       "~/Content/kendo/2016.2.504/kendo.bootstrap.min.css"));
 
        bundles.IgnoreList.Clear();
 
        bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
            "~/Content/kendo/2016.2.504/kendo.common.min.css",
            "~/Content/kendo/2016.2.504/kendo.default.min.css"));
 
 
    }
}

 

I hope to find some help, as server-side validation is crucial to go further.

Best

15 Answers, 1 is accepted

Sort by
0
Ianko
Telerik team
answered on 23 Feb 2017, 11:40 AM

Hello Yassen,

If I understand correctly, the problem is with the @Html.TextBoxFor(model => model.coin_name_2) part. This TextBoxFor is not a component from the UI for ASP.NET MVC suite, but the native MVC extensions for a textbox input. Using the basic MVC extensions and the jQuery unobtrusive validation are not components anyhow controlled by the components we provide. 

On a side note, the TextBoxFor renders a plain <input/> tag without any decoration at all. Therefore, you could easily examine the HTML and CSS rendered and see why the  is not printed. 

If, however, this is indeed related to Kendo UI or UI for ASP.NET MVC somehow, please provide a simple, locally runnable sample that demonstrates the case you have so that I can have a better look at the scenario and debug output of this code. 

Regards,
Ianko
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Yassen
Top achievements
Rank 1
answered on 23 Feb 2017, 03:07 PM

Thank Lanko,

as a matter of fact if I use Kendo as follows:

@Html.Kendo().MaskedTextBoxFor(model => model.coin_name_2).Name("coin_name_2").HtmlAttributes(new { style = "width: 100%;" })

No error message is displayed neither the red border.

Regards

0
Ianko
Telerik team
answered on 24 Feb 2017, 01:32 PM

Hello Yassen,

I created a sample project with MaskedTextBoxFor and unobtrusive jQuery validation, where everything seems to be in order. You can find attached the sample project.

On a side note, even with a plain TextBoxFor, the validation message shows up fine.

Regards,
Ianko
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Yassen
Top achievements
Rank 1
answered on 26 Feb 2017, 11:39 AM

Dear Lanko,

Thanks for the running project, unfortunately I could not fix mine according to yours.

Could you please have a look at the attached sample project to see what is causing the problem?

Try to add new record with coin_name = error.

Appreciate your feedback.

0
Yassen
Top achievements
Rank 1
answered on 26 Feb 2017, 01:23 PM

Hello Lanko,

I have found that If I copy the "CoinCustomEditor" content to the home page and add the following to the home controller the validation works.

public ActionResult Index ()
{
    return View(new IGL_coin() );
}

 

0
Yassen
Top achievements
Rank 1
answered on 27 Feb 2017, 08:46 PM
Thanks Lanko, I have found this doc http://demos.telerik.com/aspnet-mvc/grid/editing-remote-validation very helpfull
0
Yassen
Top achievements
Rank 1
answered on 10 Mar 2017, 04:07 PM

Hello Lanko,

I am terribly sorry for coming back with bad news.

the validation works for the first time only, if I insists to save the data in error for a second time it passes and get saved !!

Can you help me on this ???

0
Ianko
Telerik team
answered on 13 Mar 2017, 01:18 PM

Hello Yassen,

I tested the same using the demo you linked (http://demos.telerik.com/aspnet-mvc/grid/editing-remote-validation), but I was unable to reproduce the described behavior. Validation prevents updates every time when validation fails. 

Regards,
Ianko
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Yassen
Top achievements
Rank 1
answered on 16 Mar 2017, 02:42 PM

Dear Lanko,

I am afraid it is not true. lease have a look at the attached file, as it shows a record of the demo from your site.

Best regards

0
Yassen
Top achievements
Rank 1
answered on 16 Mar 2017, 02:48 PM

Dear Lanko,

I am afraid it is not true. Please have a look at the attached recording of the demo at your site.

regards

0
Yassen
Top achievements
Rank 1
answered on 16 Mar 2017, 02:51 PM

Sorry for multiple posts,

Here is the recording

0
Yassen
Top achievements
Rank 1
answered on 16 Mar 2017, 02:52 PM

Sorry for multiple posts,

Here is the recording

0
Ianko
Telerik team
answered on 17 Mar 2017, 07:56 AM

Hello Yassen,

The described behavior indeed happens and I can agree with you that it is strange. 

The reason for that behavior is that the idea of the remote validation is initially designed to work with a Form (https://msdn.microsoft.com/en-us/library/gg508808(vs.98).aspx). With Kendo Grid and Kendo DataSource, however, the submission cannot be stopped during the AJAX request. One option would be to make the remote validation synchronous, but jQuery dropped the async: false support. 

Typically, the scenario illustrated with the is a pure hint on how remote validation would be used in Kendo Grid. In a real-life situation, however, you will need a server validation plus the client-side remote validation for the model update to work as expected. 

I hope that clarifies further the situation and the case.

Regards,
Ianko
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Yassen
Top achievements
Rank 1
answered on 17 Mar 2017, 01:31 PM

Hello Lanko,

I know that server validation is not a option, but your answer is kind of frustrating to me.

I am evaluating the use of your controls in our app, this kind of validation is crucial to have a definite answer to go or not

Thanks

0
Ianko
Telerik team
answered on 20 Mar 2017, 07:30 AM

Hello Yassen,

Let me explain a bit further and try to clarify things with remote validation. 

Generally, remote validation is a feature of MVC provided by Microsoft with the conjunction of the jquery-validation library. Kendo Grid and Kendo Validator does not offer support for that out of the box. Such a functionality cannot be introduced as a built-in feature because jquery-validation does not offer validation over asynchronous submissions, like the one Kendo Grid does to update rows. This is why, the commonly known remote validation works only with forms. 

The demo we provide is intended to only show how to possibly implement a remote validation-like functionality with Kendo Validator and Grid by utilizing the data attributes that MVC generates for the fields.  The code shown in the demo is far from a complete solution and you should consider that only as a hint and guidance of such a feature implemented. That means that further application requirements should be accomplished by implementing code that satisfies the needs of the application. 

Due to the asynchronous nature of the implemented remote validation, there is no possible way to program a validation rule that can interact with the row submission and cancel it. 

You could possibly implement logic that would disable the button, however, the solution should be accompanied by custom code, which is related to application development and logic.

Plus, common best practices regarding validation is to have both client and server validation. Having a server validation for the same client-side validation rule would prevent model update or create and return an error to the grid.

Regards,
Ianko
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
General Discussions
Asked by
Yassen
Top achievements
Rank 1
Answers by
Ianko
Telerik team
Yassen
Top achievements
Rank 1
Share this question
or