Entity validation best practices in ASP.NET MVC and ADO.NET Entity Framework

.net asp.net-mvc entity-framework validation

Question

i am using ASP.NET MVC & ADO.NET Entity Framework in a project. I want to add validation logic to my entities via partial classes. It works similar like shown in the NerdDinner.com ASP.NET MVC Application which is using LINQ2SQL. The main difference is, that i have to use the"OnPropertyChanging" event instead the "OnValidating" like in LINQ2SQL.

There are some problems when doing it that way: - The "OnPropertyChanging" event is not the optimal point of calling validation logic, because it always triggers, even on creating a calling the default constructor. This really can cause serious problems (not only performance problems). - Together with the MVC framework there are problems when using the "EntityState.Detached" (i couldn't find any other way) to determine if a entity needs to be validated or not. Because a entity loses its entity sate during it gets displayed in the view (because on POST-event a new entity object is created instead of returning the original one).

My question is: Is there a better way of adding validation to ADO.NET Entities? I couldn't find any tutorials using a practical way of adding validation to ADO.NET Entities.

1
3
7/17/2009 8:46:43 AM

Popular Answer

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.

4
1/10/2010 4:33:34 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow