I am trying to adhere to best multi-layer design practices, and don\'t want my MVC controller to interact with my DAL (or any IRepository for that matter). It must go throug
This is how I have done it.
Have your service layer throw exceptions on business rule/validation rule failure. Create your own validation Exception for this, and include some properties to hold details of the validation error - (e.g. which property has the validation error, and what the message is)
Then create an extension method on Exception which will copy the details of the error to the ModelState (I got this idea from Steve Sandersons rather excellent 'Pro Asp.Net MVC 2 Framework' book) - if you do this right, MVC will highlight invalid fields, show errors in the UI etc.
Then your controller will contain something like this
try
{
Service.DoSomeThing();
}
catch (Exception err)
{
err.CopyTo(ModelState);
}
This means that your business rules and validation are now in your service layer, and this could be re-used.
Consider also passing DTOs / View Models to your Views, and mapping your domain objects to DTO's and (vice-versa), rather than passing your domain objects to your views.
Then the DTOs / View Models can reside in the MVC layer, and you can decorate these with the Validation attributes, and have the controller pass these to the views - thus using the built in MVC validation.
You will find that for any complex project, the validation you require at the UI end may be slightly different from what you require at the business rules end, so this helps seperate that.
There is a good library called AutoMapper which makes it easy to map from your domain objects to your DTOs (and vice versa) without a lot of boilerplate code.