web-dev-qa-db-fra.com

La validation côté client de MVC 4 ne fonctionne pas

Quelqu'un peut-il me dire pourquoi la validation côté client ne fonctionne pas dans mon application MVC 4?.

_layout.schtml

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

Dans mon web.config j'ai:

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

Dans ma page login.cshtml, j'ai:

@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>

}

Au bas de la page de connexion:

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

JavaScript est activé dans mon navigateur. Dans le projet de modèle MVC 4 à partir du client Visual Studio, la validation fonctionne correctement.

En exécutant l'application, sur la page de connexion lors de l'affichage de la source de la page, je vois ceci rendu:

<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>

et dans le bas:

<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>

Les propriétés de mon modèle sont annotées:

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 est une classe dérivée du RequiredAttribute standard. La raison en est que mes messages d'erreur sont localisés en surchargeant la méthode FormatErrorMessage(string name) de la classe RequiredAttribute. Et cela fonctionne bien - Mes étiquettes et mes messages d'erreur sont localisés.

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;
    }
}

Je mets un point d'arrêt dans la version POST de ma méthode d'action de connexion et il est touché. Le formulaire est publié sur le serveur où la validation côté serveur a lieu. La validation côté client ne se produit pas.

Qu'est-ce que je rate?

Je vous remercie.

50
Javid

J'ai eu le même problème. Il semble que les scripts de validation non intrusifs n'aient pas été chargés (voir capture d'écran à la fin). Je l'ai corrigé en ajoutant à la fin de _Layout.cshtml

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

Le résultat final:

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

À l'exception de mes jolies vues CRUD standard, tout correspond aux paramètres par défaut des modèles de projet Visual studio.

Scripts chargés après la résolution du problème: enter image description here

43
Liviu M.

Assurez-vous d’ajouter cette commande à la fin de chaque vue où vous souhaitez que les validations soient actives.

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

Dans Global.asax.cs, la méthode Application_Start () ajoute:

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

vous avez peut-être déjà résolu ce problème, mais j'ai eu un peu de chance en modifiant l'ordre de l'élément jqueryval dans BundleConfig avec App_Start. La validation côté client ne fonctionnerait pas, même sur une solution Internet MVC 4 prête à l'emploi. J'ai donc changé la valeur par défaut:

            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*"));

et maintenant ma validation côté client fonctionne. Vous voulez juste vous assurer que le fichier non intrusif est à la fin (pour que ce ne soit pas envahissant, hah :)

8
firecape

Si vous utilisez jquery.validate.js et jquery.validate.unobtrusive.js pour la validation côté client, vous devez vous rappeler que vous devez enregistrer tout attribut de validation de tout élément DOM sur votre demande. Pour cela, vous pouvez utiliser ce code:

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

pour enregistrer tous les attributs de validation. Vous pouvez appeler cette méthode sur (par exemple): $(document).ajaxSuccess() or $(document).ready() pour tous les enregistrer et votre validation peut s'effectuer avec succès au lieu d'enregistrer tous les fichiers js sur des fichiers cshtml.

7
Saeed Rajaei

Il n'y a pas d'attribut de validation de données sur votre entrée. Assurez-vous de l'avoir généré avec un utilitaire côté serveur tel que Html.TextBoxFor et qu'il se trouve dans un formulaire:

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

De plus, je ne sais pas ce qu'est le script jquery.validate.inline.js, mais s'il dépend en quelque sorte du plugin jquery.validate.js, assurez-vous qu'il est référencé après.

Dans tous les cas, consultez votre console javascript dans le navigateur pour rechercher d'éventuelles erreurs ou des scripts manquants.

7
Darin Dimitrov

J'ai finalement résolu ce problème en incluant les scripts nécessaires directement dans mon fichier .cshtml, dans cet ordre:

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

C'est un peu hors sujet, mais je suis toujours étonné par la fréquence à laquelle ce genre de choses se produit dans la programmation Web, c'est-à-dire que tout semble être en place mais qu'un obscur Tweak s'avère nécessaire pour que les choses se passent bien. Fragile, fragile, fragile.

7
user1172763

J'ai eu un problème avec la validation, le formulaire est validé, 

Cela ne fonctionne pas avec 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>

Cela fonctionne sans 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>

Hope aide quelqu'un.

3
stom

La raison pour laquelle les attributs de données de validation * n'apparaissent pas dans le code HTML rendu pour votre entrée peut être qu'il n'y a pas de contexte de formulaire. Le FormContext est créé automatiquement lorsque vous créez un formulaire à l'aide de @using(Html.BeginForm(...)) { ... }.

Si vous utilisez une balise HTML classique pour votre formulaire, vous ne recevrez pas de validation côté client.

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

Ce code a fonctionné pour moi.

2
Sam

Dans mon cas, la validation elle-même fonctionnait (je pouvais valider un élément et récupérer une valeur booléenne correcte), mais il n'y avait pas de sortie visuelle. 

Ma faute est que j'ai oublié cette ligne @ Html.ValidationMessageFor (m => ...)

Le TS a cela dans son code et m'a mis sur la bonne voie, mais je l'ai mis ici comme référence pour les autres.

2
Maarten Kieft

Pour moi, c'était beaucoup de recherches. Finalement, j'ai décidé d'utiliser NuGet au lieu de télécharger les fichiers moi-même. J'ai supprimé tous les scripts et groupements de scripts impliqués et obtenu les packages suivants (les dernières versions à ce jour)

  • jQuery (3.1.1) 
  • validation jQuery (1.15.1) 
  • Microsoft jQuery Ubobtrusive Ajax (3.2.3) 
  • Microsoft jQuery Unobtrusive Validation (3.2.3)

Puis j'ai ajouté ces bundles au fichier 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"));

J'ai ajouté cette référence à _Layout.cshtml:

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

Et j'ai ajouté cette référence à la vue dont j'avais besoin de validation:

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

Maintenant tout a fonctionné.

N'oubliez pas ces choses (beaucoup de gens les oublient):

  • Balises de formulaire (@using (Html.BeginForm ()))
  • Résumé de validation (@ Html.ValidationSummary ())
  • Message de validation sur votre entrée (exemple: @ Html.ValidationMessageFor (model => model.StartDate))
  • Configuration ()
  • L'ordre des fichiers ajoutés au paquet (comme indiqué ci-dessus)
2
Jon Koeter

la ligne ci-dessous montre que vous n'avez pas défini de DataAttribute comme requis sur AgreementNumber

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

vous avez besoin 

[Required]
public String AgreementNumber{get;set;}
1
Dr Blowhard

Dans mon cas, j’ai ajouté et id correspond au nom généré automatiquement pour VS sur le code HTML et dans le code, j’ai ajouté une ligne à ce cas.

$(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>
0
Jhon Hernández

J'ai créé ce code <form action="/StudentInfo/Edit/2" method="post" novalidate="novalidate">novalidate="novalidate" empêchait l'exécution de jQuery côté client. Lorsque j'ai supprimé novalidate="novalidate", jQuery côté client était activé et fonctionnait.

0
Sachin

Assurez-vous que vous utilisez Attributes (par exemple, RequiredAttribute), qui se trouve sous System.ComponentModel.DataAnnotations namespace.

0
Reyan Chougle

Utilisation:

@ Html.EditorFor

Au lieu de: 

@ Html.TextBoxFor

Je voudrais ajouter à ce post, que je rencontrais le même problème, mais dans un PartialView.

Et j'avais besoin d'ajouter 

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

Vers la vue partielle, même si elle est déjà présente dans la vue _Layout.

Références:

0
Hugo

Mon problème était dans web.config: UnobtrusiveJavaScriptEnabled était désactivé

<appSettings>

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

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

</appSettings>

J'ai changé et travaille maintenant:

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