Question

J'ai un modèle de vue comme celui-ci:

public class SignUpViewModel
{
    [Required(ErrorMessage = "Bitte lesen und akzeptieren Sie die AGB.")]
    [DisplayName("Ich habe die AGB gelesen und akzeptiere diese.")]
    public bool AgreesWithTerms { get; set; }
}

Le point de vue du code de balisage:

<%= Html.CheckBoxFor(m => m.AgreesWithTerms) %>
<%= Html.LabelFor(m => m.AgreesWithTerms)%>

Le résultat:

Aucune validation est exécutée. C'est d'accord jusqu'à présent parce bool est un type de valeur et jamais nulle. Mais même si je fais AgreesWithTerms cela ne fonctionnera être nulles non pas parce que le compilateur crie

« Les modèles peuvent être utilisés uniquement avec accès terrain, accès à la propriété, l'indice de tableau à une dimension ou expressions indexeur personnalisée à un seul paramètre. »

Alors, quelle est la bonne façon de gérer cette situation?

Était-ce utile?

La solution 3

Je l'ai en créant un attribut personnalisé:

public class BooleanRequiredAttribute : RequiredAttribute 
{
    public override bool IsValid(object value)
    {
        return value != null && (bool) value;
    }
}

Autres conseils

Ma solution est la suivante (il est pas très différent des réponses déjà soumises, mais je crois qu'il est nommé mieux):

/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }
}

Ensuite, vous pouvez l'utiliser comme ceci dans votre modèle:

[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }

Je voudrais créer un validateur pour le serveur et côté client. En utilisant MVC et validation de forme discrète, cela peut être réalisé simplement en procédant comme suit:

Tout d'abord, créez une classe dans votre projet pour effectuer la validation côté serveur comme ceci:

public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        if (value == null) return false;
        if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");
        return (bool)value == true;
    }

    public override string FormatErrorMessage(string name)
    {
        return "The " + name + " field must be checked in order to continue.";
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage,
            ValidationType = "enforcetrue"
        };
    }
}

Par la suite, annoter la propriété appropriée dans votre modèle:

[EnforceTrue(ErrorMessage=@"Error Message")]
public bool ThisMustBeTrue{ get; set; }

Enfin, activer la validation du côté client en ajoutant le script suivant à votre vue:

<script type="text/javascript">
    jQuery.validator.addMethod("enforcetrue", function (value, element, param) {
        return element.checked;
    });
    jQuery.validator.unobtrusive.adapters.addBool("enforcetrue");
</script>

Note:. Nous avons déjà créé une GetClientValidationRules méthode qui pousse notre annotation à la vue de notre modèle

[Compare("Remember", ErrorMessage = "You must accept the terms and conditions")]
public bool Remember { get; set; }

Cela pourrait être un « hack » mais vous pouvez utiliser le construit dans l'attribut Range:

[Display(Name = "Accepted Terms Of Service")]
[Range(typeof(bool), "true", "true")]
public bool Terms { get; set; }

Le seul problème est la chaîne « avertissement » dira « Le FIELDNAME doit être entre le vrai et vrai ».

"Obligatoire" est la mauvaise validation, ici. Vous voulez quelque chose de semblable à « doit avoir la valeur true, » qui n'est pas la même chose que « nécessaire ». Qu'en est-il d'utiliser quelque chose comme:

[RegularExpression("^true")]

Ma solution est cet attribut personnalisé simple pour les valeurs booléennes:

public class BooleanAttribute : ValidationAttribute
{
    public bool Value
    {
        get;
        set;
    }

    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value == Value;
    }
}

Ensuite, vous pouvez l'utiliser comme ceci dans votre modèle:

[Required]
[Boolean(Value = true, ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }

Je suis en train de prendre le meilleur des solutions existantes et mettre ensemble dans une seule réponse qui permet à la fois côté serveur et de validation côté client.

Le modèle à appliquer à une des propriétés pour garantir une valeur bool doit être vrai:

/// <summary>
/// Validation attribute that demands that a <see cref="bool"/> value must be true.
/// </summary>
/// <remarks>Thank you <c>http://stackoverflow.com/a/22511718</c></remarks>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    /// <summary>
    /// Initializes a new instance of the <see cref="MustBeTrueAttribute" /> class.
    /// </summary>
    public MustBeTrueAttribute()
        : base(() => "The field {0} must be checked.")
    {
    }

    /// <summary>
    /// Checks to see if the given object in <paramref name="value"/> is <c>true</c>.
    /// </summary>
    /// <param name="value">The value to check.</param>
    /// <returns><c>true</c> if the object is a <see cref="bool"/> and <c>true</c>; otherwise <c>false</c>.</returns>
    public override bool IsValid(object value)
    {
        return (value as bool?).GetValueOrDefault();
    }

    /// <summary>
    /// Returns client validation rules for <see cref="bool"/> values that must be true.
    /// </summary>
    /// <param name="metadata">The model metadata.</param>
    /// <param name="context">The controller context.</param>
    /// <returns>The client validation rules for this validator.</returns>
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        if (metadata == null)
            throw new ArgumentNullException("metadata");
        if (context == null)
            throw new ArgumentNullException("context");

        yield return new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                ValidationType = "mustbetrue",
            };
    }
}

Le code JavaScript afin d'inclure à utiliser la validation discrète.

jQuery.validator.addMethod("mustbetrue", function (value, element) {
    return element.checked;
});
jQuery.validator.unobtrusive.adapters.addBool("mustbetrue");

Pour les personnes qui ont du mal à obtenir ce travail pour la validation du côté client (moi auparavant): assurez-vous aussi

  1. Inclus <% Html.EnableClientValidation (); %> Avant la forme dans la vue
  2. occasion <% = Html.ValidationMessage ou Html.ValidationMessageFor pour le champ
  3. Création d'un DataAnnotationsModelValidator qui retourne une règle à un type de validation personnalisée
  4. a enregistré la classe dérivant de DataAnnotationsModelValidator dans le Global.Application_Start

http://www.highoncoding.com/Articles/729_Creating_Custom_Client_Side_Validation_in_ASP_NET_MVC_2_0.aspx

est un bon tutoriel sur le faire, mais misses étape 4.

La bonne façon de le faire est de vérifier le type!

[Range(typeof(bool), "true", "true", ErrorMessage = "You must or else!")]
public bool AgreesWithTerms { get; set; }

Trouver une solution plus complète ici (serveur et validation côté client):

http: / /blog.degree.no/2012/03/validation-of-required-checkbox-in-asp-net-mvc/#comments

Il suffit d'ajouter [RegularExpression]:

[DisplayName("I accept terms and conditions")]
[RegularExpression("True", ErrorMessage = "You must accept the terms and conditions")]
public bool AgreesWithTerms { get; set; }

Note - "True" doit commencer par le capital T

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top