1

Imagine User class. This class provides the only properties which are used in the database.

public class User
{
    public string Login { get; set; }
    public string Password { get; set; }
    public DateTime ActiveDateStart { get; set; }
    public DateTime ActiveDateEnd { get; set; }
}

And view model for User class with validators

public class UserViewModel: User, IValidatableObject
{
    [Required(ErrorMessage = "Enter login")]
    [RegularExpression("[a-zA-Z][a-zA-Z0-9]*", ErrorMessage = "Only alpha and digits")]
    new public string Login { get; set; }

    [Required(ErrorMessage = "Enter password")]
    new public string Password { get; set; }

    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (ActiveDateStart > ActiveDateEnd)
        {
            yield return new ValidationResult("Active period start must be before perion end date", new[] { "ActiveDateStart" });
        }
    }
}

View

<div class="form-group">
    @Html.LabelFor(m => m.Login })
    @Html.TextBoxFor(m => m.Login })
    @Html.ValidationMessageFor(m => m.Login)
</div>

<div class="form-group">
    @Html.LabelFor(m => m.Password })
    @Html.PasswordFor(m => m.Password })
    @Html.ValidationMessageFor(m => m.Password)
</div>

<div class="form-group">
    @Html.LabelFor(m => m.ActiveDateStart })
    @Html.TextBoxFor(m => m.ActiveDateStart })
    @Html.ValidationMessageFor(m => m.ActiveDateStart)
</div>

<div class="form-group">
    @Html.LabelFor(m => m.ActiveDateEnd })
    @Html.TextBoxFor(m => m.ActiveDateEnd })
    @Html.ValidationMessageFor(m => m.ActiveDateEnd)
</div>

@Html.ValidationSummary()

Controller

[HttpPost]
public ActionResult Create(UserViewModel model)
{
    if (ModelState.IsValid)
    {
        // do something
    }

    return View(model);
}

Problem

All validation specified via attributes is successfully performed and all errors successfully shown in view. But the validation made ​​through IValidatableObject don't work and no errors are displayed.

acelot
  • 752
  • 2
  • 7
  • 26
  • be more specific about you're question – lordkain Sep 16 '14 at 13:17
  • To start, I would suggest not making the base properties `new` as this is essentially duplicating the properties. Make the base class properties virtual, and override them in your ViewModel. Also, there seems to be a typo in your controller. Shouldn't it accept an argument of `UserViewModel`, not `UserModel`? When debugging, if you set a break point on the Validate method, do you hit the break point? – xDaevax Sep 16 '14 at 13:17
  • @xDaevax I'm using this class for Entity Framework and as far as I know adding virtual modificator make this property unvisible for EF – acelot Sep 16 '14 at 13:20
  • @xDaevax The Validate method is not used during the run. Breakpoint was not disturbed. – acelot Sep 16 '14 at 13:24

1 Answers1

0

I found the answer

Method Validate is not called until controller have done all the other validation.

P.S. Don't go my way. Better to look at MetaDataTypeAttribute.

acelot
  • 752
  • 2
  • 7
  • 26