Laden...

ASP.MVC 3 Checkbox auf true validieren

Erstellt von Icarus666 vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.077 Views
Icarus666 Themenstarter:in
153 Beiträge seit 2006
vor 13 Jahren
ASP.MVC 3 Checkbox auf true validieren

Ich bin dabei einen kleinen Webshop mit MVC 3 zu programmieren.

Beim Bestellvorgang werden die Artikel im Warenkorb nochmal angezeigt, damit der Kunde dies Bestätigen kann. Hierfür habe ich ein WarenkorbViewModel angelegt, welches an die View übergeben wird. Da der Kunde die AGBs beim Bestellen akzeptieren muss, habe ich hier ein Bool'sches Feld eingefügt und wollte die Validierung verwenden um zu prüfen, ob das Häkchen gesetzt ist. Da es hierfür anscheinend keine eingebaute Funktion gibt habe ich in Google eine benutzerdefiniertes Validierungsattribut (MustBeTrueAttribute) gefunden, die das machen soll. Leider scheint aber keine Client-Validierung für das Feld zu erfolgen; egal ob ich das Häkchen setze, oder nicht es geht immer weiter.


  public class WarenkorbViewModel
  {
    /// <summary>
    /// Dummy-Eigenschaft zum Akzeptieren der AGBs
    /// </summary>
    [Required]
    [MustBeTrue(ErrorMessage = "Sie müssen die AGBs akzeptieren.")]
    public bool AkzeptiereAGBs { get; set; }
  }

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

Hi,

das ist eine serverseitige Modelvalidierung was Du hier tust.
Du musst also im Controller prüfen, ob das Model gültig ist ModelState.IsValid und darauf reagieren.

Clientseitig musst Du noch einiges über jQuery machen, damit das funktioniert.
Davon rat ich aber persönlich ab.

Zudem gibt es keine Mehrzahl von AGB; es steht schließlich für Allgemeine Geschäftsbedingungen

Icarus666 Themenstarter:in
153 Beiträge seit 2006
vor 13 Jahren

Vielen Dank schon mal für die Antwort. Habe ich gleich ausprobiert.
Leider hat es nicht so funktioniert, wie ich dachte.1.ModelState.IsValid gibt immer true zurück, egal ob ich bei der Checkbox ein Häkchen setze, oder nicht. 1.Die überschriebene Funktion IsValid scheint nicht ausgefüht zu werden. Wenn ich dort einen Haltepunkt setze, passiert dort nichts.

PS: Danke für den Tipp mit den AGB.

N
4.644 Beiträge seit 2004
vor 13 Jahren

Clientseitig musst Du nicht viel machen.
Beispiel:

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

public class BooleanRequiredAttributeValidator : DataAnnotationsModelValidator<BooleanRequiredAttribute>
{
    private string _message;

    public BooleanRequiredAttributeValidator( ModelMetadata metadata, ControllerContext context, BooleanRequiredAttribute attribute ) : base( metadata, context, attribute )
    {
        this._message = attribute.ErrorMessage;
    }

    public override IEnumerable<ModelValidationResult> Validate( object container )
    {
        bool isValid = false;
        var value = Metadata.Model;
        if( Metadata.Model != null )
        {
            isValid = ( bool ) value;
        }
        else
        {
            isValid = true;
        }

        if( !isValid )
        {
            yield return new ModelValidationResult { Message = ErrorMessage };
        }
    }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
         return new ModelClientValidationRule[] { new ModelClientValidationRule() { ValidationType = "brequired", ErrorMessage = this.ErrorMessage } };
    }
}

JS:

jQuery.validator.unobtrusive.adapters.add("brequired", function (options) {
    if (options.element.tagName.toUpperCase() == "INPUT" && options.element.type.toUpperCase() == "CHECKBOX") {
        options.rules["required"] = true;
        if (options.message) {
            options.messages["required"] = options.message;
        }
    }
});

Zum Schluss noch in der Global.asax im Application_Start Event registrieren.

DataAnnotationsModelValidatorProvider.RegisterAdapter( typeof( BooleanRequiredAttribute ), typeof( BooleanRequiredAttributeValidator ) );
16.835 Beiträge seit 2008
vor 13 Jahren

Da hat sich Clientseitig ja schon einiges vereinfacht!

Zeig mal Dein Controller, Icarus.
Es ist seltsam, dass der ModelState immer noch gültig ist.

Icarus666 Themenstarter:in
153 Beiträge seit 2006
vor 13 Jahren

OK. Die serverseitige Validierung funzt. Der Tipp mit dem Controller hat geholfen.
Mir war vorher nicht klar, dass ich der Post-Funktion noch das Modell übergeben muss.


[HttpPost]                                              // v-- das wurde hinzugefügt.
public ActionResult BestellungAbschicken(WarenkorbViewModel viewModel, FormCollection values)
{
...
}

16.835 Beiträge seit 2008
vor 13 Jahren

Das FormCollection brauchst Du nicht wirklich. Das Model wird automatisch durch die Form gefüllt.

Icarus666 Themenstarter:in
153 Beiträge seit 2006
vor 13 Jahren

Ja. Hast recht, die FormCollection habe ich vorher als einziges drin gehabt. Die brauche ich jetzt nicht mehr.