Asp.Net Mvc jQuery Unobtrusive Validation input tag必须是在form里面

web.config中配置

<appSettings>
  <add key="webpages:Version" value="3.0.0.0" />
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

 

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

Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.         

 

The jQuery Unobtrusive Validation library complements jQuery Validation by adding support for specifying validation options as HTML5 data-* elements.

This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the Home repo.

Remember to make your changes to only the src file. Use ".\build.cmd" to automatically generate the js file in dist directory, minify the js file, create a .nupkg and change the version in the package.json if needed.

To stage for a release, update the "version.props" file and run ".\build.cmd" (see Release Checklist here).

 

Custom Validation Demo

https://johnnyreilly.github.io/jQuery.Validation.Unobtrusive.Native/AdvancedDemo/CustomValidation.html

看html tab和JavaScript tab里面的代码
data-rule-notequalto
jQuery.validator.addMethod("notequalto"

 

 

Ajax helper tags documentation in Asp.net Core

There are no server-side helpers, like @Ajax.Form, in ASP.NET Core. You could probably write your own tag helpers for similar features but I haven’t seen anyone do this. The general idea is to write actual JavaScript when you want to have client-side behavior. Hiding these things behind server-side magic is usually not the best idea.

jquery-ajax-unobtrusive is a JavaScript package that adds client-side behavior to look for various attributes in the final rendered page to add functionality on top of your standard forms. So this would be a fully JavaScript-based solution.

Unfortunately, there does not seem to be documentation about it. You can take a look at its source code to figure out what may or may not be possible.


jquery-ajax-unobtrusive documentation

From taking a quick look at the source (disclaimer: without testing the functionality myself), this seems to be the supported data attributes and available functionality of the package:

  • data-ajax="true" – To enable the functionality for a form.
  • data-ajax-update – Selector for the elements that are updated with the AJAX result, using the mode.
  • data-ajax-mode
    • data-ajax-mode="before" – Prepends the data to the element.
    • data-ajax-mode="after" – Appends the data to the element.
    • data-ajax-mode="replace-with" – Replaces the element with the data.
    • Otherwise sets the HTML content of the element to the data.
  • data-ajax-confirm – Message that is displayed to the user to confirm the form submission.
  • data-ajax-loading – Selector of element that is shown while loading.
  • data-ajax-loading-duration (default: 0) – Animation duration for show/hide of the loading element.
  • data-ajax-method – Allows overwriting the HTTP method for the AJAX request.
  • data-ajax-url – Allows overwriting the URL for the AJAX request.
  • data-ajax-cache – Set to other value than "true" to disable the jQuery AJAX cache parameter.
  • data-ajax-begin – Callback function before the request starts (arguments: xhr)
  • data-ajax-complete – Callback function when the request is completed (arguments: xhrstatus)
  • data-ajax-success – Callback function when the request was successful (arguments: datastatusxhr)
  • data-ajax-failure – Callback function when the request failed (arguments: xhrstatuserror)

The callback functions are the equivalent of jQuery’s beforeSendcompletesuccess, and failure. From how it looks, you can specify the callbacks using a JavaScript object path to the function.

For example data-ajax-success="foo.bar.onSuccess" will call the function foo.bar.onSuccess(), i.e. it will look for an object foo in the window, get its bar member, and call onSuccess on that.

 

 

Brad Wilson has a couple great articles on unobtrusive validation and unobtrusive ajax.
It is also shown very nicely in this Pluralsight video in the section on " AJAX and JavaScript".

Basically, it is simply Javascript validation that doesn't pollute your source code with its own validation code. This is done by making use of data- attributes in HTML.

 

 

 

Custom client-side validation    微软官方教程

Custom client-side validation is done by generating data- HTML attributes that work with a custom jQuery Validation adapter. The following sample adapter code was written for the [ClassicMovie] and [ClassicMovieWithClientValidator] attributes that were introduced earlier in this article:

$.validator.addMethod('classicmovie', function (value, element, params) {
    var genre = $(params[0]).val(), year = params[1], date = new Date(value);

    // The Classic genre has a value of '0'.
    if (genre && genre.length > 0 && genre[0] === '0') {
        // The release date for a Classic is valid if it's no greater than the given year.
        return date.getUTCFullYear() <= year;
    }

    return true;
});

$.validator.unobtrusive.adapters.add('classicmovie', ['year'], function (options) {
    var element = $(options.form).find('select#Movie_Genre')[0];

    options.rules['classicmovie'] = [element, parseInt(options.params['year'])];
    options.messages['classicmovie'] = options.message;
});

For information about how to write adapters, see the jQuery Validation documentation.

The use of an adapter for a given field is triggered by data- attributes that:

  • Flag the field as being subject to validation (data-val="true").
  • Identify a validation rule name and error message text (for example, data-val-rulename="Error message.").
  • Provide any additional parameters the validator needs (for example, data-val-rulename-param1="value").

The following example shows the data- attributes for the sample app's ClassicMovie attribute:

<input class="form-control" type="date"
    data-val="true"
    data-val-classicmovie="Classic movies must have a release year no later than 1960."
    data-val-classicmovie-year="1960"
    data-val-required="The Release Date field is required."
    id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">

As noted earlier, Tag Helpers and HTML helpers use information from validation attributes to render data- attributes. There are two options for writing code that results in the creation of custom data- HTML attributes:

  • Create a class that derives from AttributeAdapterBase<TAttribute> and a class that implements IValidationAttributeAdapterProvider, and register your attribute and its adapter in DI. This method follows the single responsibility principal in that server-related and client-related validation code is in separate classes. The adapter also has the advantage that since it is registered in DI, other services in DI are available to it if needed.
  • Implement IClientModelValidator in your ValidationAttribute class. This method might be appropriate if the attribute doesn't do any server-side validation and doesn't need any services from DI.

 

添加自定义规则

 https://github.com/aspnet/jquery-validation-unobtrusive/blob/master/src/jquery.validate.unobtrusive.js#L257

 adapters.add = function (adapterName, params, fn) {
        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
        /// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
        /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
        /// mmmm is the parameter name).</param>
        /// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
        /// attributes into jQuery Validate rules and/or messages.</param>
        /// <returns type="jQuery.validator.unobtrusive.adapters" />
        if (!fn) {  // Called with no params, just a function
            fn = params;
            params = [];
        }
        this.push({ name: adapterName, params: params, adapt: fn });
        return this;
    };

 循环的时候用到adapter name

https://github.com/aspnet/jquery-validation-unobtrusive/blob/master/src/jquery.validate.unobtrusive.js#L196

$.each(this.adapters, function () {
                var prefix = "data-val-" + this.name,
                    message = $element.attr(prefix),
                    paramValues = {};

                if (message !== undefined) {  // Compare against undefined, because an empty message is legal (and falsy)
                    prefix += "-";

                    $.each(this.params, function () {
                        paramValues[this] = $element.attr(prefix + this);
                    });

                    this.adapt({
                        element: element,
                        form: form,
                        message: message,
                        params: paramValues,
                        rules: rules,
                        messages: messages
                    });
                }
            });

 

 

 

 

 

 如何找到需要验证的元素

 https://github.com/aspnet/jquery-validation-unobtrusive/blob/master/src/jquery.validate.unobtrusive.js#L242

在html加载完成之后,可以直接找到所有需要验证的,$("form").find("[data-val=true]")

 parse: function (selector) {
            /// <summary>
            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
            /// with the [data-val=true] attribute value and enables validation according to the data-val-*
            /// attribute values.
            /// </summary>
            /// <param name="selector" type="String">Any valid jQuery selector.</param>

            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
            // element with data-val=true
            var $selector = $(selector),
                $forms = $selector.parents()
                    .addBack()
                    .filter("form")
                    .add($selector.find("form"))
                    .has("[data-val=true]");

            $selector.find("[data-val=true]").each(function () {
                $jQval.unobtrusive.parseElement(this, true);
            });

            $forms.each(function () {
                var info = validationInfo(this);
                if (info) {
                    info.attachValidation();
                }
            });

 

  如何触发jquery validation的init函数的

https://github.com/aspnet/jquery-validation-unobtrusive/blob/master/src/jquery.validate.unobtrusive.js#L428

 $(function () {
        $jQval.unobtrusive.parse(document);
    });

 

https://github.com/aspnet/jquery-validation-unobtrusive/blob/master/src/jquery.validate.unobtrusive.js#L249

parse方法里面

   info.attachValidation();
        parse: function (selector) {
            /// <summary>
            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
            /// with the [data-val=true] attribute value and enables validation according to the data-val-*
            /// attribute values.
            /// </summary>
            /// <param name="selector" type="String">Any valid jQuery selector.</param>

            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
            // element with data-val=true
            var $selector = $(selector),
                $forms = $selector.parents()
                    .addBack()
                    .filter("form")
                    .add($selector.find("form"))
                    .has("[data-val=true]");

            $selector.find("[data-val=true]").each(function () {
                $jQval.unobtrusive.parseElement(this, true);
            });

            $forms.each(function () {
                var info = validationInfo(this);
                if (info) {
                    info.attachValidation();
                }
            });
        }
    };

 

https://github.com/aspnet/jquery-validation-unobtrusive/blob/master/src/jquery.validate.unobtrusive.js#L154

$form.validate()  这里调用了jquery validation的validate方法,里面会new一个jquery validation,构造函数里面init会触发事件绑定

  attachValidation: function () {
                    $form
                        .off("reset." + data_validation, onResetProxy)
                        .on("reset." + data_validation, onResetProxy)
                        .validate(this.options);
                },

 

 如何查看jQuery.validator.unobtrusive.adapters里面adapter对应的方法内容

adapt的[[FunctionLocation]]可以定位到具体代码

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-03-31 15:27  ChuckLu  阅读(554)  评论(0编辑  收藏  举报