1

Ich verwende idiotensicher in einem MVC-Projekt. Ich habe Probleme, wo es scheint, als würde es einen Textvergleich durchführen, um herauszufinden, ob die Enddatumszeit größer ist als die Startdatumszeit. Hiermit idiotensicher, um sicherzustellen, dass Enddatum ist größer als Startdatum

ist das Modell:

public class TestModel 
{ 
    [Required] 
    [DataType(DataType.DateTime)] 
    public DateTime start { get; set; } 

    [Required] 
    [DataType(DataType.DateTime)] 
    [GreaterThan("start")] 
    public DateTime end { get; set; } 
} 

die Ansicht

@model WebApplication1.Models.TestModel 

@{ 
    ViewBag.Title = "Home Page"; 
} 


@using (Html.BeginForm("Index2", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 
{ 
    @Html.AntiForgeryToken() 

    @Html.ValidationSummary("", new { @class = "text-danger" }) 
    <div class="form-group"> 
     @Html.LabelFor(m => m.start, new { @class = "col-md-2 control-label" }) 
     <div class="col-md-10"> 
      @Html.TextBoxFor(m => m.start, "{0:dd/MM/yyyy HH:mm}", new { @class = "form-control datetimepicker" }) 
     </div> 
    </div> 
    <div class="form-group"> 
     @Html.LabelFor(m => m.end, new { @class = "col-md-2 control-label" }) 
     <div class="col-md-10"> 
      @Html.TextBoxFor(m => m.end, "{0:dd/MM/yyyy HH:mm}", new { @class = "form-control datetimepicker" }) 
     </div> 
    </div> 
    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Set password" class="btn btn-default" /> 
     </div> 
    </div> 
} 

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

Der Controller

public ActionResult Index() 
    { 
     TestModel model = new TestModel(); 
     // model.start = new DateTime(2016, 5, 31); 
     //model.end = new DateTime(2016, 8, 31); 
     model.start = DateTime.Now; 
     model.end = DateTime.Now.AddMinutes(30); 
     return View(model); 
    } 

Sie mein Projekt herunterladen können aus ausprobieren: https://www.dropbox.com/s/pf0lkg297hq0974/WebApplication1.zip?dl=0

Es gibt zwei Probleme: 1) Wenn Sie das Startdatum 11/07/2016 23:51 und das Enddatum 02/08/2016 00:21 eingeben, erhalten Sie einen Überprüfungsfehler, da das Enddatum kleiner ist als der Starttermin Datum. Es scheint wie ein Textvergleich zu mir.

2) Auch wenn Sie die beiden Initialisierungsanweisungen model.start und model.end auskommentieren, erhalten Sie beim Übermitteln ein ungültiges Datum.

Hinweis Ich habe bootstrap datetimepicker verwendet, aber das Bit auskommentiert, wo es initialisiert wird, wenn das Dokument fertig ist. Ich dachte, es hätte etwas mit dem Problem zu tun, scheint aber nicht. Schließlich möchte ich auch datetimepicker arbeiten lassen.

Beachten Sie auch, ich in Australien bin so das Datumsformat tt/mm/jjjj

+0

Ich vermute hier narrensicher ist fehlerhaft. Gibt es eine andere Möglichkeit, die Annotation zu überprüfen? – rukiman

+0

Das Problem ist die 'jquery.validate.js' (verwendet von idiotensicher) validiert Daten basierend auf' MM/TT/JJJJ' Format (also 'Ende = 02/08/2016' ist 8. Februar und' Start = 11/07/2016 ist der 7. Dezember, was bedeutet, dass "Ende" kleiner ist als "Start". Für einige Optionen siehe [diese Antwort] (http://stackoverflow.com/questions/39677035/date-of-birth-validation-keeps-showing/39682410#39682410). –

+0

Auch [diese Antwort] (http://stackoverflow.com/questions/27285458/jquery-ui-datepicker-and-mvc-view-model-type-datetime/27286969#27286969) wenn Sie den jquery-ui datepicker verwenden (Ich nehme an, Bootstrap datetimepicker wird auch eine ähnliche Methode haben, um den Wert zu einem bestimmten Datumsformat zu analysieren.) –

Antwort

1

in Ihrem HTML-ur Posting Index2 das ändern zum Index Convert String Zurück zu Datetime in GreaterThanAttribute in der Anwendung ist und dann vergleichen

versuchen, dies habe ich diese Implementierung getestet

Der Controller

public class TestController : Controller 
{ 
    // GET: Test 

    [HttpGet] 
    public ActionResult Index() 
    { 

     var model = new TestModel(); 
     // model.start = new DateTime(2016, 5, 31); 
     //model.end = new DateTime(2016, 8, 31); 
     model.start = DateTime.Now; 
     model.end = DateTime.Now.AddMinutes(30); 
     return View(model); 


    } 
    [HttpPost] 
    public ActionResult Index(TestModel model) 
    { 
     if (ModelState.IsValid) 
     { 

      // model.start = new DateTime(2016, 5, 31); 
      //model.end = new DateTime(2016, 8, 31); 
      model.start = DateTime.Now; 
      model.end = DateTime.Now.AddMinutes(30); 
      return View("Index", model); 
     } 
     return View("Index", model); 

    } 
} 

Yo ur TestModel

public class TestModel 
{ 
    [Required] 
    [DataType(DataType.DateTime)] 
    public DateTime start { get; set; } 

    [Required] 
    [DataType(DataType.DateTime)] 
    [GreaterThan("start", "Your Error Message")] 
    public DateTime end { get; set; } 
} 

Ihre GreaterThenAttribute.cs

public class GreaterThanAttribute : ValidationAttribute, IClientValidatable 
{ 

    public string otherPropertyName; 
    public GreaterThanAttribute() 
    { 
    } 
    public GreaterThanAttribute(string otherPropertyName, string errorMessage) : base(errorMessage) 
    { 
     this.otherPropertyName = otherPropertyName; 
    } 

    protected override ValidationResult IsValid 
     (object value, ValidationContext validationContext) 
    { 
     ValidationResult validationResult = ValidationResult.Success; 
     try 
     { 
      // Using reflection we can get a reference to the other date property, in this example the project start date 
      var containerType = validationContext.ObjectInstance.GetType(); 
      var field = containerType.GetProperty(this.otherPropertyName); 
      var extensionValue = field.GetValue(validationContext.ObjectInstance, null); 
      var datatype = extensionValue.GetType(); 

      //var otherPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(this.otherPropertyName); 
      if (field == null) 
       return new ValidationResult(String.Format("Unknown property: {0}.", otherPropertyName)); 
      // Let's check that otherProperty is of type DateTime as we expect it to be 
      if ((field.PropertyType == typeof(DateTime) || 
       (field.PropertyType.IsGenericType && field.PropertyType == typeof(Nullable<DateTime>)))) 
      { 
       DateTime toValidate = (DateTime)value; 
       DateTime referenceProperty = (DateTime)field.GetValue(validationContext.ObjectInstance, null); 
       // if the end date is lower than the start date, than the validationResult will be set to false and return 
       // a properly formatted error message 
       if (toValidate.CompareTo(referenceProperty) < 1) 
       { 
        validationResult = new ValidationResult(ErrorMessageString); 
       } 
      } 
      else 
      { 
       validationResult = new ValidationResult("An error occurred while validating the property. OtherProperty is not of type DateTime"); 
      } 
     } 
     catch (Exception ex) 
     { 
      // Do stuff, i.e. log the exception 
      // Let it go through the upper levels, something bad happened 
      throw ex; 
     } 

     return validationResult; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules 
     (ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), 
      ValidationType = "isgreater", 
     }; 
     rule.ValidationParameters.Add("otherproperty", otherPropertyName); 
     yield return rule; 
    } 
} 
+0

verstehe ich nicht ganz. Kannst du Code einfügen? – rukiman

+0

@rukiman Ich habe meine Antwort aktualisiert und den Code eingefügt – gurdeep

Verwandte Themen