Using VAB with Linq to Sql or Entities

Topics: Validation Application Block
Apr 27, 2008 at 5:51 PM
Is there any guidance on how to use the VAB with business objects generated via the Linq to Sql or Entity designers? Or will the VAB be replaced by the attributes from System.ComponentModel.DataAnnotations.dll, coming with ASP.NET dynamic data?
May 13, 2008 at 11:22 PM
I have a similar question. It seems the direction LINQ to SQL is going is to perform the validations in partial classes in the "On[COLUMNNAME]Changing" (example: OnOrderDateChanging) method.
The alternative to use dynamic data and the use of defining the MetaData class in order to decorate a LINQ class with attributes for validation seems quite tedious.
Either approach really fuses the data tier and the business tier quite tightly (same dll) together.
I've ususally had the business tier in a different dll (and well unit tested) from the data tier (virutally always auto-generated).
Does the use of LINQ mean that your data tier and business tier are basically one tier? (one dll)
I'm just starting to use the VAB and liked it.
May 18, 2008 at 7:43 PM
Edited May 18, 2008 at 7:50 PM
Update (just after I pressed the send button I see that 4.0 was release about 48 hours ago...)
Looks like the changes to the VAB might meet my needs... I'll try that.
(Here's the link: http://msdn.microsoft.com/en-us/library/cc511712.aspx#Changes_Validation )

Original Post:

Wouldn't it be nice if the validators would work on methods that had only one parameter, and they would validate that single parameter ('value' in this case)?
Eample:
Since we can't seem to do this:

public class Person
{
    
private string emailAddress = string.Empty; 
    [
RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]
    public string EmailAddress { get { return emailAddress; } }
}

 

 

 

Let us do this (in Ent Lib 4.0?):

public partial class Person
{
    [

RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"]
    partial void OnEmailChanging(string value)
    {
    }
}

 

 

I guess I'm not ready to give up yet... It's a long story, but if you look at this classic Data Access Object structure (http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html ) you see the DataSource, DataAccessObject, TransferObject, and the BusinessObject.
It seems everytime I see an implementation of this I see some logic in at least three places.... sometimes four.

Unless I'm missing something, in LINQ, the Entity (before any extension with the partial class) is the Transfer Object.
The DataContext is the DataAccessObject, and the BusinessObject is the extension of the Entity using the partial class capability.
I've come to not like this pattern due to the fact logic ends up in so many places.
Here are things I tried:
1) Set properties on Entities as virtual - example: if my table were called entity_Person I would then write Person : entity_Person for the derived class... However, the DataContext does not know about this Person class, only the entity_Person. If the DataContext did, then I could override the properties I wanted to validate. Thus I can't seem to get this to work.
2) Use Self Validation in the partial class... Example:

[

HasSelfValidation()]
public partial class Person
{
    
// This section does the validation.
    
private ValidationResults _validationResults = new ValidationResults();
    [
SelfValidation()]
    public void DoValidate(ValidationResults results)
    {
        results.AddAllResults(_validationResults);
    }

    ///
<summary>
    /// Used to initially removed the ValidationResult with the Key of key
    /// if such an entry exists. This way if a value is corrected between
    /// validations, then you will not get an improper value for IsValid.
    /// </summary>
    /// <param name="key"></param>
    private void RemoveValidationResult(string key)
    {
        ValidationResults resultsToKeep = new ValidationResults();
        foreach (ValidationResult result in _validationResults)
            
if (string.CompareOrdinal(result.Key, key) != 0)
                resultsToKeep.AddResult(result);
        _validationResults = resultsToKeep;
    }

 

 

 

    partial void OnEmailChanging(string value)
    {
        string key = "Email";
        RemoveValidationResult(key);
        Regex rx = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
        
if (!rx.IsMatch(value))
            _validationResults.AddResult(
new ValidationResult(string.Format("'{0}' is not a valid e-mail address.", value), this, key, "", null));
    }

 

}

 

I hope this makes sense and that I've not made a mistake.

So now back to the original insightful question: Will VAB be extended to support LINQ? Or will VAB be replaced by DataAnnotations in Dynamic Data?
May 18, 2008 at 8:26 PM

Drat... Maybe 4.1?
I wish the item at the bottom said:
The Validation Application Block ignores attributes attached to parameters except for LINQ methods supported by INotifyPropertyChanging, WCF and the Policy Injection Application Block Validation Call Handler.
Instead of:
The Validation Application Block ignores attributes attached to parameters except for WCF and the Policy Injection Application Block Validation Call Handler.

Here's the text from the Ent Lib 4.0 Using Attirbutes section:
Validation Attribute Targets

Jul 8, 2008 at 3:12 PM
I'm a little confused, are you saying there that it didn't work?