1
votes

I am trying to implement data validation in my asp.net mvc 2 app, following scott gu's nice post here : http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

I now need more than basic validation (Required, Range, StringLength...)

I want to implement a duplicate checker, but unfortunately his post starts to lose detail in the custom validation part.

See:

Step 4: Creating a Custom [Email] Validation Attribute

The System.ComponentModel.DataAnnotations namespace within the .NET Framework includes a number of built-in validation attributes that you can use. We’ve used 4 different ones in the sample above - [Required], [StringLength], [Range], and [RegularExpression].

You can also optionally define your own custom validation attributes and use them as well. You can define completely custom attributes by deriving from the ValidationAttribute base class within the System.ComponentModel.DataAnnotations namespace. Alternatively, you can choose to derive from any of the existing validation attributes if you want to simply extend their base functionality.

So this is what I ahve so far...Where do I go from here ???

(Please note I have simplified this for the sake of my problem, I realize to check duplicate people objects in real life you would have to do more than check first and last name)

[MetadataType(typeof(PersonMetaData))]
public partial class Person
{
    //Validation rules for the Person class

    [Bind(Exclude = "PersonID")]
    public class PersonMetaData
    {
        //[DisplayName("Person")]
        [Required(ErrorMessage =  "A Person Code is required")]
        [DuplicatePerson(ErrorMessage = "Bad!")]
        public object PersonCode { get; set; }
    }
}

public class DuplicatePersonAttribute : ValidationAttribute
{
    readonly PeopleDB peopleDB = new PeopleDB();

    public  bool IsDuplicate(object value)
    {
        //var isDuplicate = peopleDB.People.Select(x => x.PersonCode == value);
        
        //Return false if duplicate in DB

        return false;
    }
}
2
I'd start with "what overrides are available from ValidationAttribute?" I've tended to just use Custom Validation because of the nicety of having the validation methods on the same class.Matt Mills

2 Answers

0
votes

Here's something I'm using to enforce unique emails in user registration:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class UniqueEmailAttribute : ValidationAttribute { public UniqueEmailAttribute() : base("The value for '{0}' is already taken") { }

public override bool IsValid( object value )
{
    string toCheck = value as string;
    if( String.IsNullOrEmpty(toCheck) ) return false;

    return ( DataRepository.GetMembersByEmail(toCheck).Count() == 0 );
}

[Inject]
public IDataRepository DataRepository { get; set; }

}

The only thing that may not be reasonably self-explanatory here is the [Inject] attribute decorating the DataRepository property. It's provided by the nInject library as a means of doing dependency injection (inversion of control) so that I can separate database access from the application. But prior to incorporating DI I just had the attribute create an instance of the concrete DataRepository object and used that (that's not good practice, of course, which is why I went the nInject route).

-1
votes

Following the SoC (Separation of Concern), you shouldn't do this kind of validation on the model but rather on the controller.