Проверка на стороне клиента MVC 4 не работает

Может кто-нибудь сказать мне, почему проверка на стороне клиента не работает в моем приложении MVC 4.

_layout.schtml

@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)

В моем web.config у меня есть:

<appSettings>
   <add key="ClientValidationEnabled" value="true" />
   <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

На моей странице login.cshtml у меня есть:

@using (Html.BeginForm())
{
    <div class="formscontent">

        <ol>
            <li>
                @Html.LabelFor(x => x.AgreementNumber)
                <br />
                @Html.TextBoxFor(x => x.AgreementNumber, new { size = "30" })
                <br />
                @Html.ValidationMessageFor(m => m.AgreementNumber)
                <br />
                <br />
            </li>
            <li>
                @Html.LabelFor(x => x.UserName)
                <br />
                @Html.TextBoxFor(x => x.UserName, new { size = "30" })
                <br />
                @Html.ValidationMessageFor(m => m.UserName)
                <br />
                <br />
            </li>
            <li>
                @Html.LabelFor(x => x.Password)
                <br />
                @Html.PasswordFor(x => x.Password, new { size = "30" })
                <br />
                @Html.ValidationMessageFor(m => m.Password)
                <br />
                <br />
            </li>
        </ol>

    </div>

    <ol>
        <li>
            @Html.CheckBoxFor(m => m.RememberMe)
            @Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
        </li>
    </ol>

    <br />

    <input class="mainbutton" type="submit" value="@Model.Localisation.TranslateHtmlString("LogonBtn")" /><br />
    <div style="text-align: left; padding: 0 5px 5px 10px;">
        Forgot login-info? clik <a class="link" href="@Url.Action("Index", "Credentials")">here.</a>
    </div>

}

В нижней части страницы входа в систему:

@section Scripts {
  @Scripts.Render("~/bundles/jqueryval")
}

JavaScript включен в моем браузере. В шаблонном проекте MVC 4 от клиента Visual Studio валидация работает отлично.

Запустив приложение, на странице входа в систему при просмотре исходного кода я вижу, что это отображается:

<label for="AgreementNumber">number</label>
<br />
<input id="AgreementNumber" name="AgreementNumber" size="30" type="text" value="387893" />
<br />
<span class="field-validation-valid" data-valmsg-for="AgreementNumber" data-valmsg-  replace="true"></span>

и в этом внизу:

<script src="/BMWebsite/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/BMWebsite/Scripts/jquery.validate.inline.js"></script>
<script src="/BMWebsite/Scripts/jquery.validate.js"></script>
<script src="/BMWebsite/Scripts/jquery.validate.unobtrusive.js"></script>

Свойства моей модели аннотированы:

public class LogonModel : ModelBase
{
    [MyRequired("AgreementNumberRequiredProperty")]
    [MyDisplay("AgreementNumberLabel")]
    public string AgreementNumber { get; set; }

    [MyRequired("UserNameRequiredProperty")]
    [MyDisplay("UserNameLabel")]
    public string UserName { get; set; }

    [MyRequired("PasswordRequiredProperty")]
    [DataType(DataType.Password)]
    [MyDisplay("PasswordLabel")]
    public string Password { get; set; }

    [MyDisplay("RememberMeCheckBox")]
    public bool RememberMe { get; set; }
}

MyRequired это класс, производный от обычного RequiredAttribute. Причина в том, что мои сообщения об ошибках локализуются путем переопределения FormatErrorMessage(string name) метод RequiredAttribute учебный класс. И все работает нормально - мои ярлыки и сообщения об ошибках локализованы.

MyRequired.cs

public class MyRequiredAttribute : RequiredAttribute
{
    private readonly string _errorMessagekey;

    public MyRequiredAttribute(string errorMessage)
    {
        _errorMessagekey = errorMessage;
    }

    public override string FormatErrorMessage(string name)
    {
        var translation = HttpContext.Current.Session["translation"] as LocalisationHelper;

        return translation != null ? translation.Translate(_errorMessagekey) : ErrorMessage;
    }
}

Я установил точку останова в версии POST моего метода действия входа в систему, и его ударили. Форма отправляется на сервер, где происходит проверка на стороне сервера. Проверка на стороне клиента не происходит.

Что мне не хватает?

Спасибо.

19 ответов

У меня такая же проблема. Кажется, что ненавязчивые сценарии проверки не были загружены (см. Скриншот в конце). Я исправил это, добавив в конце _Layout.cshtml

 @Scripts.Render("~/bundles/jqueryval")

Конечный результат:

   @Scripts.Render("~/bundles/jquery")
   @Scripts.Render("~/bundles/jqueryval")
   @RenderSection("scripts", required: false)

За исключением моих довольно стандартных CRUD-представлений, все по умолчанию является шаблоном проекта Visual Studio.

Загруженные скрипты после исправления проблемы:

Обязательно добавляйте эту команду в конце каждого представления, где вы хотите, чтобы проверки были активными.

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Я наконец решил эту проблему, включив необходимые скрипты прямо в мой файл.cshtml, в следующем порядке:

<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

Это немного не по теме, но я постоянно удивляюсь тому, как часто подобные вещи случаются в веб-программировании, то есть все кажется на месте, но некоторые неясные настройки оказываются необходимыми для развития событий. Хлипкий, хрупкий, хрупкий.

В Global.asax.cs метод Application_Start() добавляет:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyRequiredAttribute), typeof(RequiredAttributeAdapter));

Возможно, вы уже решили эту проблему, но мне повезло, изменив порядок элемента jqueryval в BundleConfig с помощью App_Start. Проверка на стороне клиента не будет работать даже на новом готовом интернет-решении MVC 4. Поэтому я изменил значение по умолчанию:

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));

в

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*",
                    "~/Scripts/jquery.unobtrusive*"));

и теперь моя проверка на стороне клиента работает. Вы просто хотите убедиться, что ненавязчивый файл находится в конце (так что это не навязчиво, ха:)

Если вы используете jquery.validate.js а также jquery.validate.unobtrusive.js для проверки на стороне клиента вы должны помнить, что вы должны зарегистрировать любой атрибут проверки любого элемента DOM по вашему запросу. Для этого вы можете использовать этот код:

$.validator.unobtrusive.parse('your main element on layout');

зарегистрировать все атрибуты проверки. Вы можете вызвать этот метод (например):$(document).ajaxSuccess() or $(document).ready() зарегистрировать все из них, и ваша проверка может быть успешно проведена вместо регистрации всех файлов js в файлах cshtml.

На вашем входе нет атрибутов проверки данных. Убедитесь, что вы сгенерировали его с помощью помощника на стороне сервера, такого как Html.TextBoxFor, и что он находится внутри формы:

@using (Html.BeginForm())
{
    ...
    @Html.TextBoxFor(x => x.AgreementNumber)
}

Также я не знаю, что jquery.validate.inline.js сценарий, но если это как-то зависит от jquery.validate.js Плагин убедитесь, что на него ссылаются после него.

Во всех случаях посмотрите на вашу консоль javascript в браузере на предмет возможных ошибок или отсутствующих скриптов.

Для меня это было много поисков. В конце концов я решил использовать NuGet вместо загрузки файлов самостоятельно. Я удалил все задействованные сценарии и наборы сценариев и получил следующие пакеты (последние версии на данный момент)

  • jQuery (3.1.1)
  • Проверка jQuery (1.15.1)
  • Microsoft jQuery Ubobtrusive Ajax (3.2.3)
  • Ненавязчивая проверка Microsoft jQuery (3.2.3)

Затем я добавил эти пакеты в файл BundleConfig:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js"));

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                "~/Scripts/jquery.validate.js",
                "~/Scripts/jquery.validate.unobtrusive.js",
                "~/Scripts/jquery.unobtrusive-ajax.js"));

Я добавил эту ссылку в _Layout.cshtml:

@Scripts.Render("~/bundles/jquery")

И я добавил эту ссылку к любому представлению, которое мне нужно было проверить:

@Scripts.Render("~/bundles/jqueryval")

Теперь все работает.

Не забывайте эти вещи (многие люди забывают их):

  • Теги формы (@using (Html.BeginForm()))
  • Сводка проверки (@Html.ValidationSummary())
  • Сообщение о проверке вашего ввода (Пример: @Html.ValidationMessageFor(model => model.StartDate))
  • Конфигурация ()
  • Порядок файлов, добавляемых в комплект (как указано выше)

У меня была проблема с проверкой, форма сообщений, затем она проверяет,

Это не работает с JQuery CDN

    <script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Это работает без JQuery CDN

<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Надежда помогает кому-то.

Моя проблема была в web.config: UnobtrusiveJavaScriptEnabled был отключен

<appSettings>

<add key="ClientValidationEnabled" value="true" />

<add key="UnobtrusiveJavaScriptEnabled" value="false" />

</appSettings>

Я изменился на и теперь работает:

`<add key="UnobtrusiveJavaScriptEnabled" value="true" />`

Это работает для меня, перейдите к вашему классу модели и установите сообщение об ошибке над любой опорой

[Required(ErrorMessage ="This is Required Field")]
    public string name { get; set; }

import пространство имен для Требуется Ctrl+. и, наконец, добавьте это в поле зрения

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Причиной того, что атрибуты data-* проверки не отображаются в визуализированном html для вашего ввода, может быть отсутствие контекста формы. FormContext создается автоматически при создании формы с использованием @using(Html.BeginForm(...)) { ... },

Если вы используете обычный HTML-тег для своей формы, вы не получите проверку на стороне клиента.

<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

Этот код работал для меня.

В моем случае сама валидация работала (я мог проверить элемент и получить правильное логическое значение), но визуального вывода не было.

Моя ошибка была в том, что я забыл эту строку @Html.ValidationMessageFor(m => ...)

У TS есть это в его коде, и я оказался на правильном пути, но я поместил это здесь как ссылку для других.

Строка ниже показывает, что вы не установили DataAttribute, как это требуется для AgreementNumber

<input id="AgreementNumber" name="AgreementNumber" size="30" type="text" value="387893" />

тебе нужно

[Required]
public String AgreementNumber{get;set;}

Я создал этот HTML <form action="/StudentInfo/Edit/2" method="post" novalidate="novalidate"> где novalidate="novalidate" препятствовал выполнению jQuery на стороне клиента, когда я удалил novalidate="novalidate"Клиентский JQuery был включен и начал работать.

Я хотел бы добавить к этому сообщению, что у меня возникла та же проблема, но в PartialView.

И мне нужно было добавить

<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Частичное представление, даже если оно уже присутствует в представлении _Layout.

Рекомендации:

В моем случае я добавил, и id равен имени, автоматически сгенерированному для VS в html, и в коде я добавил строку для этого случая.

$(function () {
            $.validator.addMethod('latinos', function (value, element) {
                return this.optional(element) || /^[a-záéóóúàèìòùäëïöüñ\s]+$/i.test(value);
            });

            $("#btn").on("click", function () {
                //alert("aa");
                $("#formulario").validate({                    
                    rules:
                    {
                        email: { required: true, email: true, minlength: 8, maxlength: 80 },
                        digitos: { required: true, digits: true, minlength: 2, maxlength: 100 },
                        nombres: { required: true, latinos: true, minlength: 3, maxlength: 50 },
                        NombresUsuario: { required: true, latinos: true, minlength: 3, maxlength: 50 }
                    },
                    messages:
                    {
                        email: {
                            required: 'El campo es requerido', email: 'El formato de email es incorrecto',
                            minlength: 'El mínimo permitido es 8 caracteres', maxlength: 'El máximo permitido son 80 caracteres'
                        },
                        digitos: {
                            required: 'El campo es requerido', digits: 'Sólo se aceptan dígitos',
                            minlength: 'El mínimo permitido es 2 caracteres', maxlength: 'El máximo permitido son 10 caracteres'
                        },
                        nombres: {
                            required: 'El campo es requerido', latinos: 'Sólo se aceptan letras',
                            minlength: 'El mínimo permitido es 3 caracteres', maxlength: 'El máximo permitido son 50 caracteres'
                        },
                        NombresUsuario: {
                            required: 'El campo es requerido', latinos: 'Sólo se aceptan letras',
                            minlength: 'El mínimo permitido es 3 caracteres', maxlength: 'El máximo permitido son 50 caracteres'
                        }
                    }
                });
            });

<tr>@*<div class="form-group">     htmlAttributes: new { @class = "control-label col-md-2" }      , @class = "form-control" }*@
                <td>@Html.LabelFor(model => model.NombresUsuario )</td>

                        @*<div class="col-md-10">*@
                <td>
                    @Html.EditorFor(model => model.NombresUsuario, new { htmlAttributes = new { id = "NombresUsuario" } })
                    @Html.ValidationMessageFor(model => model.NombresUsuario, "", new { @class = "text-danger" })
                </td>

Убедитесь, что вы используете Attributes (например RequiredAttribute) который подпадает под System.ComponentModel.DataAnnotations пространство имен

Использование:

@ Html.EditorFor

Вместо:

@ Html.TextBoxFor

  @section Scripts
 {
<script src="../Scripts/jquery.validate-vsdoc.js"></script>
<script src="../Scripts/jquery.validate.js"></script>
<script src="../Scripts/jquery.validate.min.js"></script>
<script src="../Scripts/jquery.validate.unobtrusive.js"></script>
<script src="../Scripts/jquery.validate.unobtrusive.min.js"></script>
}
Другие вопросы по тегам