The attribute validation is perfectly good for what it can do. In addition to the validation attributes you mention, you have the EmailAddress attribute which validates the given property as an e-mail address.
[EmailAddress(ErrorMessage = "Invalid Email Address")]
Then you have the RegularExpression validation attribute for doing more complicated custom validations:
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Characters are not allowed.")]
For conditional validation and such things, you can add that logic to your controller and add errors to the ModelState as needed.
Example:
if (MyProperty == "something" && MyOtherProperty != "something")
{
ModelState.AddModelError("", "MyOtherProperty needs to be something")
}
If you don't want such boilerplate validation code in your controller logic, you can write your own custom validation attributes. By doing so, you can pretty much validate whatever you can think of.
There's plenty of resources about that topic on the Internet.
How to create a custom validation attribute?
How to create Custom Data Annotation Validators
To name a few.