2012-12-07 12 views
12

Ho un ViewModel per la mia prject MVC4 contenente due proprietà DateTime:C# attributo per verificare se una data è precedente rispetto agli altri

[Required] 
[DataType(DataType.Date)] 
public DateTime RentDate { get; set; } 

[Required] 
[DataType(DataType.Date)] 
public DateTime ReturnDate { get; set; } 

C'è un modo semplice per utilizzare C# attributi come [Compare("someProperty")] per controllare superare la il valore della proprietà RentDate è precedente al valore di ReturnDate?

+1

Perché si desidera utilizzare * attributi * per questo? Quando vorresti che fosse applicato? Come validazione? –

+0

Credo che dovrebbe essere convalidato sul client attraverso la validazione lib. Quindi, per sicurezza, è possibile convalidare il back-end, aggiungendo errori a modelstate. – TNCodeMonkey

+0

Perché vuoi confrontare? Il tuo scopo è limitare il valore dell'uno all'altro? Potresti provare a cercare "coercizione", così viene chiamato in WPF. Purtroppo non posso aiutarti con asp.net. –

risposta

22

Qui è un'implementazione di base molto veloce (senza controllo degli errori, ecc) che dovrebbe fare quello che chiedi (solo sul lato server ... non farà convalida javascript lato client asp.net). Non l'ho provato, ma dovrebbe essere sufficiente per iniziare.

using System; 
using System.ComponentModel.DataAnnotations; 

namespace Test 
{ 
    [AttributeUsage(AttributeTargets.Property)] 
    public class DateGreaterThanAttribute : ValidationAttribute 
    { 
     public DateGreaterThanAttribute(string dateToCompareToFieldName) 
     { 
      DateToCompareToFieldName = dateToCompareToFieldName; 
     } 

     private string DateToCompareToFieldName { get; set; } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      DateTime earlierDate = (DateTime)value; 

      DateTime laterDate = (DateTime)validationContext.ObjectType.GetProperty(DateToCompareToFieldName).GetValue(validationContext.ObjectInstance, null); 

      if (laterDate > earlierDate) 
      { 
       return ValidationResult.Success; 
      } 
      else 
      { 
       return new ValidationResult("Date is not later"); 
      } 
     } 
    } 


    public class TestClass 
    { 
     [DateGreaterThan("ReturnDate")] 
     public DateTime RentDate { get; set; } 

     public DateTime ReturnDate { get; set; } 
    } 
} 
+0

Implementazione piacevole. –

+0

Era esattamente quello che stavo cercando, grazie mille! – cLar

3

Sembra che si sta utilizzando in modo DataAnnotations un'altra alternativa è quella di implementare IValidatableObject nel modello di visualizzazione:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
{ 
    if (this.RentDate > this.ReturnDate) 
    { 
     yield return new ValidationResult("Rent date must be prior to return date", new[] { "RentDate" }); 
    } 
} 
3

Se si utilizza .NET Framework 3.0 o superiore che si potrebbe fare come un'estensione di classe ...

/// <summary> 
    /// Determines if a <code>DateTime</code> falls before another <code>DateTime</code> (inclusive) 
    /// </summary> 
    /// <param name="dt">The <code>DateTime</code> being tested</param> 
    /// <param name="compare">The <code>DateTime</code> used for the comparison</param> 
    /// <returns><code>bool</code></returns> 
    public static bool isBefore(this DateTime dt, DateTime compare) 
    { 
     return dt.Ticks <= compare.Ticks; 
    } 

    /// <summary> 
    /// Determines if a <code>DateTime</code> falls after another <code>DateTime</code> (inclusive) 
    /// </summary> 
    /// <param name="dt">The <code>DateTime</code> being tested</param> 
    /// <param name="compare">The <code>DateTime</code> used for the comparison</param> 
    /// <returns><code>bool</code></returns> 
    public static bool isAfter(this DateTime dt, DateTime compare) 
    { 
     return dt.Ticks >= compare.Ticks; 
    } 
0

Modello:

[DateCorrectRange(ValidateStartDate = true, ErrorMessage = "Start date shouldn't be older than the current date")] 
public DateTime StartDate { get; set; } 

[DateCorrectRange(ValidateEndDate = true, ErrorMessage = "End date can't be younger than start date")] 
public DateTime EndDate { get; set; } 

classe Attribute:

[AttributeUsage(AttributeTargets.Property)] 
    public class DateCorrectRangeAttribute : ValidationAttribute 
    { 
     public bool ValidateStartDate { get; set; } 
     public bool ValidateEndDate { get; set; } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      var model = validationContext.ObjectInstance as YourModelType; 

      if (model != null) 
      { 
       if (model.StartDate > model.EndDate && ValidateEndDate 
        || model.StartDate > DateTime.Now.Date && ValidateStartDate) 
       { 
        return new ValidationResult(string.Empty); 
       } 
      } 

      return ValidationResult.Success; 
     } 
    } 
Problemi correlati