Pergunta

I'm creating ASP.NET MVC 4 web project for creating events. Events have start and end dates. I created my custom validation attribute to prevent saving Event model (class) instance if start date already started. Here is code of custom validation attribute:

public class NoPastDateAttribute : ValidationAttribute
{
    public NoPastDateAttribute()
        : base(ValidationStrings.DateStarted)
    {
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            var valueDate = DateTime.Parse(value.ToString());
            if (valueDate < DateTime.Now)
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }
        return ValidationResult.Success;
    }
}

When I create a new instance of Event model (class) there is no problem. My custom validation attribute works fine. It validates start date and prevents saving if start date already started. However, when I edit already created Event instance, (for instance I changed Name), my validation attribute don't let me save this new name, because of startdate. (if startdate already started)

Here is my Event model (class):

public class Event
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    [NoPastDate]
    public DateTime StartDate { get; set; }

    public DateTime EndDate { get; set; }


}

How can i fix this problem?

UPDATE: I used Colin's advise and added implementation of IValidatableObject interface and also added RowVersion (timeStamp). It helped me, but I'm not sure how efficient this solution is. So, here is my updated class:

public class Event : IValidatableObject
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public byte[] RowVersion { get; set; }

    public DateTime StartDate { get; set; }

    public DateTime EndDate { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (RowVersion == null && this.StartDate < DateTime.Now)
        {
            yield return
                new ValidationResult("Date already started");
        }

    }
}
Foi útil?

Solução

Put your attribute on a ViewModel used to Create and have a different ViewModel for Edit. And/Or implement IValidatableObject to implement model level validation, checking whether the ID is the default for its type as a test for creating or editing:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (ID == Guid.Empty && this.StartDate < DateTime.Now)
    {
        yield return
            new ValidationResult("Date already started");
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top