Personally, I don't put validation in the objects themselves. I use the xVal library to handle my entity validation.
xVal encourages you to annotate your entity classes (or, actually, metadata companion classes) with attributes that describe the various validation rules. These validation attributes are the default ones that come with .NET in System.ComponentModel.DataAnnotations.
You then run validation against your objects manually in your business layer. This is done by using a method that runs the System.ComponentModel.DataAnnotations validation logic. I wrote one that looks like this:
/// <summary>
/// Gets the validation errors for the passed in object by using reflection to retrieve the
/// <see cref="ValidationAttribute"/>s placed on its properties or on the properties of the object's
/// metadata class (as specified by a <see cref="MetadataTypeAttribute"/> placed on the object's class)
/// </summary>
/// <param name="instance">The object to validate</param>
/// <returns>Any validation errors</returns>
/// <remarks>
/// Borrowed (and cleaned up) from
/// http://goneale.com/2009/03/04/using-metadatatype-attribute-with-aspnet-mvc-xval-validation-framework/
/// </remarks>
public static IEnumerable<ErrorInfo> Validate(object instance)
{
//Try to get the MetadataType attribute from the object
MetadataTypeAttribute metadataAttrib = instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();
//If the MetadataType attribute existed, get the metadata class
//else just use the class of the object
Type buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : instance.GetType();
IEnumerable<PropertyDescriptor> buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>();
IEnumerable<PropertyDescriptor> modelClassProperties = TypeDescriptor.GetProperties(instance.GetType()).Cast<PropertyDescriptor>();
//This query matches each property on the model class against the buddy class
//gets a list of all invalid validation attributes and returns a list of
//validation errors
return from buddyProp in buddyClassProperties
join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
from attribute in buddyProp.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(modelProp.GetValue(instance))
select new ErrorInfo(buddyProp.Name, attribute.FormatErrorMessage(String.Empty), instance);
}
xVal provides a neat exception type you can throw that encapsulates validation errors and allows you to easily add them to the ModelState in your Controller.
xVal also will autogenerate client-side JavaScript form validation code for you by leveraging jQuery.Validate by providing an HtmlHelper method.
Check out http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/ for a walkthrough on how it works. I've found it to be very nice way of doing validation that's not a total chore. It fits right in in the ASP.NET MVC way of doing things.