2

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 Answer 1

1

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);

Sign up to request clarification or add additional context in comments.

8 Comments

I arrived at the same conclusion that AutoMapper needs to be involved, but I was hoping I was wrong. The problem occurs when say loading up an "Edit" View. You read the id parameter in and then go fetch the object that needs to be edited before passing it to the View. At that point, you need to somehow set the values inside the ViewModel based on the object you fetched. This is where all paths lead to hell otherwise AutoMapper. I can make this entire architecture work perfectly well with two different validation rule sets, but setting the retrieved object's values for edit is where it blows.
But why don't you want to use automapper? - it's perfect for exactly this scenario, simple to use and performant. You can almost forget it's there.
I will probably resort to using it and I appreciate your very valid point, but I am very strict on trying to minimise the number of foreign/add-on components I bring into my systems. From experience, 3 years down the track, suddenly ASP.Net MVC10 is released and your whole solution won't build because you're running a really old version of AutoMapper and whatever other add-on DLLs.. My first preference is always to try really hard to use native tools first before resorting to add-ons. As a general rule, the more add-ons, the less reliability and higher the future maintenance..
I understand your concern, but there are some great tools out there now for .NET, especially useful for MVC (e.g. ORMs, IoC containers etc.) In my opinion you are just generating more work for yourself by not using them out of principle. Stuff like Automapper has very focussed scope, and has no dependencies on high level stuff like MVC. Personally I'm more wary of using the MS stuff with the product lock-ins and closed source! (your Linq-to-SQL for example;)
No good: Trying to map MyProject.Data.Employee to admin.ViewModels.Employee. Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. What's going on?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.