2
votes

I'm using DataAnnotations for validation of a custom class (LINQ to SQL auto generated) using the MetadataType tag on top of the class. I'm loving DataAnnotations and it works well in simple, common scenarios. E.g.

[MetadataType(typeof(Person_Validation))]
public class Person

But what if you need to have two different sets of validation rules applied to the class in different scenarios???

My situation: Some fields are mandatory on the www public-facing site, but not mandatory on the internal admin site. But both sites have a View which "Creates New" of the same object/class.

This is where it becomes DataAnnotations HELL surfaces..

I've tried using two different ViewModels with different validation applied to each of them, two classes that inherit from Person with different validation applied to each of them. But all roads seem to conflict with DRY principals and you end up somewhere along the line having the totally respecify all properties for the underlying class structure. You don't have to do this when you just have one validation rule set. So it very quickly becomes hell and not practical for complex objects.

Is this possible using DataAnnotations and what is the best DRY architecture?

1

1 Answers

1
votes

Not sure what you mean by 'virtually duplicate and manually set each and every property manually in the original underlying class'. I've never liked the idea of buddy classes, and would personally recommend different view models for Admin and Public site (with appropriate validation set on each), and then mapping between the models using AutoMapper.

UPDATE:

Regading Automapper, the basic usage is something like this:

  • First you have to define your mappings. This lets automapper figure out in advance how to map objects. You only need to do this once in the application, so a good place to do this in an ASP.NET app is in Application_Start() in Global.asax. For each pair of classes you want to map between, call: Mapper.CreateMap<SourceType, DestinationType>();

  • Then, in your application code to do the map you just use:

var destinationObject = Mapper.Map<SourceType, DestinationType>(sourceOjbect);