Recommended approach for model validation that needs to touch the Db - asp.net-mvc

Up to now, most of our validation is performed using validation attributes on our view models.
One additional validation check we need to perform is to validate that a string doesn't already exist in our database.
Originally I was just handling this check within the controller action and then adding an error into ModelState if required. However, I would rather make use of the built-in validation infrastructure.
One method I tried was implementing IValidateableObject on my viewmodel. This feels a bit wrong as I'm calling DependencyResolver:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var viewModel = validationContext.ObjectInstance as EditPostViewModel;
if (viewModel != null)
{
var slug = (Slug)viewModel.Slug;
var repo = DependencyResolver.Current.GetService<IRepository<Post>>();
var existing = repo.Get(p => p.Slug == slug && p.Id != viewModel.Id);
if (existing != null)
yield return new ValidationResult("Duplicate slug.", new[] { "Slug" });
}
}
Another approach I thought about was using a custom ValidationAttribute. To me this only makes sense if I can re-use it on multiple viewmodels and to re-use it I need to be able to construct a generic repository interface (as per the above code) as I may need IRepository<Foo> or IRepository<Bar> depending on the Model.
Remote Validation is great but I still need to the validation server side.
So what would people recommend or have used themselves to achieve something similar.
Note that I do have unique database constraints on this column but don't want to fall back to exception handling to perform this validation.
Solution
I had a look as the asp.net article #Darin suggested. This approach definitely works, but the article is a bit flawed in that whilst it manages to decouple the validation service away from any direct references to ModelState, you instead end up with a circular dependency where controller depends on the validation service and the validation service depends on ModelState (via a wrapper); which doesn't exist until the controller is created. Nice!
Instead I exposed the IValidationDictionary as a public property on my validation service and set this in my controllers constructor:
slugValidator.ValidationDictionary = new ModelStateWrapper(this.ModelState);
The rest is kind of application specific but essentially I created a validator for each type of "slugable" entity I wanted to validate. These were then injected by my container.
public interface ISlugValidator<TEntity> where TEntity : ISlugable {
IValidationDictionary ValidationDictionary { get; set; }
bool ValidateSlug(Guid? entityId, Guid featureId, Slug slug);
}
I call ValidateSlug(...) just before I check ModelState.IsValid in my controller actions.
This is a good solution for the level of validation I need currently and the fact that most of it can be handled using Data annotations. If my validation/business rules get more complex I will probably switch to FluentValidation (this also works well with Depenency Injection) as it's better suited for externalizing validation logic.

I would recommend doing this type of validation at the service layer and not bother with data annotations.

Related

MVC Validation: Service Layer or Data Annotations

I hope this isn't terribly subjective, but when it comes to validating business logic, I see two paths that, unless I'm mistaken, deliver pretty much the same result:
Use a service layer where all validation on your models is performed (ref: http://www.asp.net/mvc/tutorials/older-versions/models-%28data%29/validating-with-a-service-layer-cs)
Decorate your models with Data Annotations
In the first instance, the model is a dumb container for data, and in the second, the model knows about its valid state. Above and beyond that, is there nuance between the two that I'm missing? Should one be used over the other in some instances?
Thanks,
Chris
In my opinion, you could keep the basic validation (required fields, regex fields, comparative fields etc...) on your Model (InputModel) with Data Annotations or Fluent Validation, and your bussiness validation in service layer. I think the Annotations is much more to create a screen validation and inputs to server side than business validation. If you keep the business at the service layer you must remember to create a ModelState Wrapper to integrate it with Asp.Net MVC, and show it on the view.
Take a look at a samepl of ModelState Wrapper:
public class ModelStateWrapper : IValidationDictionary
{
private ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
#region IValidationDictionary Members
public void AddError(string key, string errorMessage)
{
_modelState.AddModelError(key, errorMessage);
}
public bool IsValid
{
get { return _modelState.IsValid; }
}
#endregion
}
They are not mutually exclusive, you can use attributes for "static" rules, and service layer validation for "dynamic" rules (e.g. check for uniqueness).
Quoting the tutorial you referred to:
In this tutorial, you learn how to move your validation logic out of
your controllers and into a separate service layer.
Well, the model decorated with data annotation attributes does not have to be in the web project next to the controller, it can be in the service layer next to the service, which means all validation logic is in one place.

in a well-constructured cms-type system where in the architecture should a business object be created?

This is a question regarding architecture.
Let's say that I have created a layered system in ASP.NET MVC with a good domain layer which uses the repository pattern for data-access. One of those domain objects is Product. At the CMS-side I have a view for creating and editing products. And I have a front-end where that product should be shown. And these views differ considerably so that a different viewmodel for them is appropriate.
1) Where should a new Product object be created when the user enters data for a new product in the data entrance view? In the controller? But making the controller responsible for object creation could hurt the Single Responsibility principle. Or should the factory pattern be used? That would mean that the factory would be very specific, because the data entered would be passed 'as is' to the factory. So coding against an IProductFactory would not be possible, because the input data is specific to that data entrance view. So is it right that we have a tight coupling between this controller and the factory?
2) The Product viewmodel to be shown at the frontend, where should that come from? The answer seems to me a ViewModelFactory that takes the domain object Product and creates a view from it. But again, this viewmodelfactory would be specific for this view, because the viewmodel we are asking for is specific. So is it right then that the controller and the viewmodelfactory would be tightly coupled?
3) Validation: The input data should be validated at the frontend, but the domain layer should also validate the product (because the domain layer knows nothing about the UI and does not even know IF the UI does validation and thus should not depend upon validation there). but where should the validation go? The ProductFactory seems to be a good choice; it seems to me that that adheres to SRP, if the task of a product factory is described as 'creating valid product objects.'
But perhaps the Product business object should contain the validation. That seems more appropriate because validation of a product will not only be needed at creation time but at other places as well. But how can we validate a Product that is not yet created? Should the Product business object then have methods like IsNameValid, IsPriceValid etc??
I'm going to answer your second question first.
Yes, viewmodels should be tightly coupled with the controller. You shouldn't need a ViewModelFactory though. Something like AutoMapper or ValueInjecter should be good enough for converting domain Product to ProductViewModel.
As for your first question, you should keep your domain Product Factory separate from your controller. There are a few different approaches you could use. One would be creating a factory method that only takes scalar values as method arguments -- for example string, bool, etc, other primitives, and pure .NET types.
You can then have your controller pass the scalars to the factory method from the viewmodel. This is loosely coupled, and highly cohesive.
For example:
[HttpPost]
public ActionResult CreateProduct(ProductViewModel model)
{
if (ModelState.IsValid)
{
// assuming product factory is constructor-injected
var domainProduct = _productFactory.BuildProduct(
model.Name, model.Price, model.Description);
// ... eventually return a result
}
return View(model);
}
Another approach is to put the methods for passing viewmodel properties directly on the domain object, but for this approach, it is best to make your property setters non-public:
[HttpPost]
public ActionResult CreateProduct(ProductViewModel model)
{
if (ModelState.IsValid)
{
// assuming no product factory
var domainProduct = new Domain.Product();
domainProduct.SetName(model.Name);
domainProduct.SetPrice(model.Price);
domainProduct.SetDescription(model.Description);
// ... eventually return a result
}
return View(model);
}
I prefer the first option because it's less verbose, and keeps object creation in your domain layer. However both are loosely coupled, because you are not sharing viewmodel types between your MVC layer and your domain layer. Instead your higher layer (MVC) is taking a dependency in the domain layer, but your domain layer is free from all MVC concerns.
Response to first 2 comments
Second comment first, re validation: It doesn't necessarily have to be the product factory's responsibility to enforce validation, but if you want to enforce business rules in the domain, validation should happen at the factory or lower. For example, a product factory could instantiate a product and then delegate build operations to methods on the entity -- similar to the SetXyzProperty methods above (difference being those methods might be internal to the domain lib instead of public). In this case, it would be the product entity's responsibility to enforce validation on itself.
If you throw exceptions to enforce validation, those would bubble up through the factory and into the controller. This is what I generally try to do. If a business rule ever ends up bubbling to the controller, then it means MVC is missing a validation rule and ModelState.IsValid should be false. Also, this way you don't have to worry about passing messages back from the factory -- business rule violations will come in the form of an exception.
As for your first comment, yes: MVC takes a dependency on the domain, not vice versa. If you wanted to pass a viewmodel to the factory, your domain would be taking a dependency on whatever lib the viewmodel class is in (which should be MVC). It's true that you could end up with a lot of factory method args, or factory method overload explosion. If you find this happening, it might be better to expose more granular methods on the entity itself than relying on the factory.
For example, you might have a form where the user can quickly click to change just the name or price of a Product, without going through the whole form. That action could even happen over ajax using JSON instead of a full browser POST. When the controller handles it, it might be easier to just invoke myProduct.SetPriceOrName(object priceOrName) instead of productFactory.RePriceOrRename(int productId, object priceOrName).
Response to question update
Others may have different opinions, but in mine, the business domain should not expose a validation API. That's not to say you can't have an IsValidPrice method on the entity. However, I don't think it should be exposed as part of the public API. Consider the following:
namespace NinetyNineCentStore.Domain
{
public class Product
{
public decimal Price { get; protected set; }
public void SetPrice(decimal price)
{
ValidatePrice(price);
Price = price;
}
internal static bool IsPriceValid(decimal price)
{
return IsPriceAtLeast99Cents(price)
&& IsPriceAtMostNineteen99(price)
&& DoesPriceEndIn99Cents(price);
}
private static bool IsPriceAtLeast99Cents(decimal price)
{
return (price >= 0.99m);
}
private static bool IsPriceAtMostNineteen99(decimal price)
{
return (price <= 19.99m);
}
private static bool DoesPriceEndIn99Cents(decimal price)
{
return (price % 1 == 99);
}
private static void ValidatePrice(decimal price)
{
if (!IsPriceAtLeast99Cents(price))
throw new InvalidOperationException(
"Product price must be at least 99 cents.");
if (!IsPriceAtMostNineteen99(price))
throw new InvalidOperationException(
"Product price must be no greater than 19.99.");
if (!DoesPriceEndIn99Cents(price))
throw new InvalidOperationException(
"Product price must end with 99 cents.");
}
}
}
The above encapsulates validation on the entity, without exposing it in the API. Your factory can still invoke the internal IsPriceValid, but doesn't need to be concerned with every little business rule permutation. When any client, internal or public, tries to violate the rule, an exception is thrown.
This pattern might seem like overkill, but consider business rules that involve more than one property on an entity. For example, say you can break the DoesPriceEndIn99Cents rule when the Product.IsOnSale == true. You already have ValidatePrice encapsulated, so you can accommodate that rule without having to expose a new validation API method.

MVC3 Service Layer Validation. Returning Exception, Custom Object, Model State Dictionary?

Just curious on your thoughts or experiences around service layer validation.
I have to process fairly standard validation such as "object with name property doesn't already exist", but I wasn't sure how to return these validation failures back to the controller.
My initial thought was to implement a standard List<ValidationError> but I've seen it done each and every way so was curious the pros/cons of each.
Thanks for any input.
If you go with System.ComponentModel.DataAnnotations entries you can (as you seem to know) decorate your properties with required and many more tags
public class Person
{
[Required(ErrorMessage="object with name property doesn't already exist")]
public string Name { get; set; }
}
although I personally use ViewModels rather than exposing domain mdoels to the view, your controller action can now do something like:
[HttpPost]
public ActionResult SavePerson(Person model)
{
if (ModelState.IsValid)
{
// your model validates - do things
return RedirectToAction("success view here");
}
return View(model);
}
This is one of the standard 'post' handler patterns in MVC. This is the simplest path to getting your object model validating in my opinion.
From there, there are a few other options - your domain object can implement IValidatedableObject and you can yield return the errors (see http://buildstarted.com/2010/09/20/mvc-3s-ivalidatableobject/ as an example).
I'd recommend not mixing the two though, as if you are using dataannotations and have even a single invalid property, the IsValid method on IValidatableObject will not be called.
From there, there's lots you can do with custom validation attributes (the extended version of IsValid seems to give you more flexibility http://msdn.microsoft.com/en-us/library/gg480674%28v=vs.98%29.aspx)
Hope some of the above helps - once you get past the basics there's a lot you can do with it and things like client validation of custom attributes etc. are all fun.
Cheers,
Terry
[edit to add:
After re-reading your post, it may be that you want to only validate at the service layer? If so, I've used the following approach:
public void Setname(string newName)
{
Validator.ValidateProperty(newName, new ValidationContext(this, null, null) { MemberName = "Name" });
Name = newName;
}
obviously your Name property would need a { get; private set; } for this, though you could always add the Validator.ValidateProperty into an extended setter for the public property either.
]
On a new project I'm working on (first time mvc) I've been using the ms code contracts (which throw exceptions) and do all the validation on my domain objects themselves. For things that can't be validated there (such as validations that require database access) I validate in my services and throw exceptions. Additionally like the poster above I have whole separate view models for everything that have data annotations validators on them. The exceptions bubble up and I catch them in the controller and append to the ModelState. There's a lot of overlap with those and the view model validation but it's not much extra effort and allows me to vary the validation per view and yet still have the "core" validations be required.
The book pro asp mvc 2 has another nice way - write a class that inherits Exception and contains a collection of errors. Then you do your validations, add to the collection then throw the exception then he catches it in the controller and copies over to ModelState. This method will let you catch ALL the errors in one exception instead of just one at the service layer.

ASP.NET MVC: Is Data Annotation Validation Enough?

I'm using the Data Annotation validation extensively in ASP.NET MVC 2. This new feature has been a huge time saver, as I'm now able to define both client-side validation and server-side validation in one place. However, while I was doing some detailed testing, I realized that it's quite easy for someone to bypass the server-side validation if I relied on Data Annotation validation alone. For example, if I defined a required field by annotating the property with the [Required] attribute and placed a textbox for that required field in a form, a user could simply remove the textbox from the DOM (which can easily be done through Firebug) and now the Data Annotation validation will not be triggered on that property during ModelBinding inside of a Controller. To ensure that the "required" validation is triggered, I can repeat the validation after ModelBinding happens, but then I'd be repeating my validation logic.
What is everyone's recommendation on validation? Is Data Annotation validation enough? Or does the validation need to be repeated to ensure that validations get triggered in all situations?
Follow-up comment:
Based on the answers below, it seems that I can't rely on the Model Binder and Data Annotation validation alone. Since we're concluding that additional server-side validation is required, is there an easy way for my Service layer to trigger validation based on what's been defined in the Data Annotations? It seems that this will get us the best of both words...we won't need to repeat the validation code, but we'll still ensure that the validation gets executed even if Model Binder doesn't trigger it.
I'm going to post this follow-up comment as a separate question, as it poses a different question than the original one.
I think to be vigilant concerning security you should choose to you make server validation the priority and ensure that this is always your fallback. Your server validation should work without the client validation. Client validation is more for UX and tho that is paramount to your design, it is secondary to security. With this in mind you will find yourself repeating your validation. A goal is often trying to design your app so that the server and client validation can be integrated as much as possible to reduce the work required to validate on the server and the client. But be assured you must do both.
If bypassing the client validation (by means of DOM manipulation) is avoiding the server validation (which it seems you are indicating) then your server validation for this instance may not be employed appropriately. You should be invoking your server validation again in your controller action or in a service layer. The scenario you describe should not be defeating your server validation.
With the scenario you describe, the DataAnnotation attributes method should be sufficient. It seems that you simply need to make a few code changes to ensure that your server validation is invoked also when submitting the form.
I paired xVal with DataAnnotations and have written my own Action filter that checks any Entity type parameters for validation purposes. So if some field is missing in the postback, this validator will fill ModelState dictionary hence having model invalid.
Prerequisites:
my entity/model objects all implement IObjectValidator interface which declares Validate() method.
my attribute class is called ValidateBusinessObjectAttribute
xVal validation library
Action filter code:
public void OnActionExecuting(ActionExecutingContext filterContext)
{
IEnumerable<KeyValuePair<string, object>> parameters = filterContext.ActionParameters.Where<KeyValuePair<string, object>>(p => p.Value.GetType().Equals(this.ObjectType ?? p.Value.GetType()) && p.Value is IObjectValidator);
foreach (KeyValuePair<string, object> param in parameters)
{
object value;
if ((value = param.Value) != null)
{
IEnumerable<ErrorInfo> errors = ((IObjectValidator)value).Validate();
if (errors.Any())
{
new RulesException(errors).AddModelStateErrors(filterContext.Controller.ViewData.ModelState, param.Key);
}
}
}
}
My controller action is defined like this then:
[ValidateBusinessObject]
public ActionResult Register(User user, Company company, RegistrationData registrationData)
{
if (!this.ModelState.IsValid)
{
return View();
}
...
}
The DataAnnotation is certainly not enough. I use it extensively also to pre-validate my calls to the domain model to get better error reporting and fail as early as possible.
You can however tweak the DataAnnotation Model yourself to ensure properties with [Required] MUST be posted. (will follow up with code later today).
UPDATE
Get the source for DataAnnotations Model Binder and find this line in DataAnnotationsModelBinder.cs
// Only bind properties that are part of the request
if (bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey)) {
Change it to
// Only bind properties that are part of the request
bool contextHasKey = bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey);
bool isRequired = GetValidationAttributes(propertyDescriptor).OfType<RequiredAttribute>().Count() > 0;
if (contextHasKey || (!contextHasKey && isRequired)) {
I wrote my own ValidationService for MVC 1.0 by copying patterns from both xVal's DataAnnotationsRuleProvider and Microsoft's DataAnnotationsModelBinder (and Martijn's comments). The service interface is below:
public interface IValidationService
{
void Validate(object instance);
IEnumerable<ErrorInfo> GetErrors(object instance);
}
public abstract class BaseValidationService : IValidationService
{
public void Validate(object instance)
{
var errors = GetErrors(instance);
if (errors.Any())
throw new RulesException(errors);
}
public abstract IEnumerable<ErrorInfo> GetErrors(object instance);
}
The service is a validation runner that walks the property tree of the object instance it receives and actually executes the validation attributes that it finds on each property, building a list of ErrorInfo objects when attributes are not valid. (I'd post the whole source but it was written for a client and I don't know yet if I'm authorized to do so.)
You can then have your controllers, business logic services explicitly invoke validation when you are ready, rather than relying exclusively on the model binder for validation.
There are a couple of other pitfalls that you should be aware of:
The default DataTypeAttribute in data
annotations doesn't actually do any
data type validation, so you'll need
to write a new attribute that
actually uses xVal regular
expressions (or something else) to
perform server-side data type
validation.
xVal doesn't walk
properties to create client-side
validation, so you may want to make
some changes there to get more robust
client-side validation.
If I am allowed and have time, I will try to make more source available...
See codeProject Server-side Input Validation using Data Annotations
Input validation can be done automatically on the client side in
ASP.NET MVC or explicitly validating the model against the rules. This
tip will describe how it can be done manually on the server-side of an
ASP.NET applications or within the repository code of WPF
applications.
// Use the ValidationContext to validate the Product model against the product data annotations
// before saving it to the database
var validationContext = new ValidationContext(productViewModel, serviceProvider: null, items:null);
var validationResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(productViewModel, validationContext,validationResults, true);

Using MVC and fluent Nhibernate, how do I validate unique fields on my ViewModel before I bind them to my Domain Object and Save them?

I have a website where I allow users to create new Part records. I'm trying to figure out the best way to validate specific fields for uniqueness. I want to make sure that somebody doesn't try to add a Part with PartNumber 1234 if that PartNumber already exists on a different Part.
The Web Application is using Asp.net MVC with fluent nHibernate for mapping my objects to the database. I'm using Castle validation on my view models for things like ValidateNonEmpty, ValidateRange, etc. Should I use the ValidateSelf method to query the repository to see if that part number already exists? Something doesn't feel right about using my Repository on the ViewModel.
Would it be better for me to place that logic on the controller action? That doesn't seem right because I expect my ViewModel to already be Validated at the point (during ModelBind).
Or maybe its none of the above. Thanks for any help on this one.
UPDATE
Ok, not sure if this will help, but here is what my Save action looks like for a typical Create Action in my project:
public ActionResult Create(PartViewModel viewModel)
{
//I think I'd like to know if its Valid by this point, not on _repository.Save
if(ModelState.IsValid)
{
try
{
var part = _partCreateViewModelMap.MapToEntity(viewModel);
_repository.Save(part);
return Redirect("~/Part/Details/" + part.Id);
}
catch (Exception e)
{
// skip on down...
}
}
// return view to edit
return View(viewModel);
}
I have been asked this question many times. My friends were worried about whether they can perform data access from the validator code. The answer is simple. If you need to do this, you should do it. Usually we need to do such checks at each level of abstraction. And after all checks you should be ready to catch an exception, caused by unique constraint violation.
If you define a unique constraint within the database, then why not delegate the responsibility to check for whether a unique value already exists to the database? Using NHibernate, you can use the NHibernate.Exceptions.ISQLExceptionConverter interface to capture and transform known errors relating to constraint violations. You can also use NHibernate.Exceptions.IViolatedConstraintNameExtracter implementers (see NHibernate.Exceptions.TemplatedViolatedConstraintNameExtracter) to get at the grubby details of your database exception, and transform it into a user-friendly message, repackage as a validation exception of your chosing and catch it in the relevant controller.
Example of a quick, very specific quick and dirty exception converter from one of my projects:
Imports NHibernate
Imports NHibernate.Exceptions
Imports System.Data.SqlClient
Imports System.Data.Common
Namespace NHibernate
Public Class ConstraintViolationExceptionConverter
Implements ISQLExceptionConverter
Public Function Convert(ByVal adoExceptionContextInfo As Global.NHibernate.Exceptions.AdoExceptionContextInfo) As System.Exception Implements Global.NHibernate.Exceptions.ISQLExceptionConverter.Convert
Dim dbEx As DbException = ADOExceptionHelper.ExtractDbException(adoExceptionContextInfo.SqlException)
If TypeOf dbEx Is SqlException Then
Dim sqlError As SqlException = DirectCast(dbEx, SqlException)
Select Case sqlError.Number
Case 547
Return New ConstraintViolationException(adoExceptionContextInfo.Message, adoExceptionContextInfo.SqlException)
End Select
End If
Return SQLStateConverter.HandledNonSpecificException(adoExceptionContextInfo.SqlException, adoExceptionContextInfo.Message, adoExceptionContextInfo.Sql)
End Function
End Class
End Namespace
Configured through the web.config/nhibernate-configuration/session-factory property element:
<property name="sql_exception_converter">csl.NHibernate.ConstraintViolationExceptionConverter, csl</property>
Edit: Should probably mention that the converter interface has changed in recent versions of NHibernate, the interface from this example is from NHibernate.dll v2.1.0.4000
I typically put a Service layer between my controllers and repositories.
The service layer would then handle the validation and calls to the repository.
Then, if there's a validation error in the service layer, I throw a custom exception, catch it in the controller, and inject the errors in to the model state.
I have no answer for your question but you can check sharparchitecture.net site. It contains some best practives for asp.net mvc and nhibernate. Also I can recommend you to check xval project and tutorials about Validating with Data Annotation Validators
I have found the solution that works for me is to
1.) Ask if the entity is valid to execute your validation work.
2.) After this is complete you should have something on your object to show it's valid or not (in my case I use a CSLA like concept of "broken rules").
3.) If you have something like this you can verify the object is valid before NHibernate tries to persist it as shown below.
The only issue with this approach is that you do need to implement an interface on each entity requiring validation. If you can live with this it will stop NHibernate from persisting the changes of an object that's not valid according to your rules.
using System;
using NHibernate;
using NHibernate.Event;
using Validation.Entities.Interfaces;
using Persistence.SessionBuilder;
namespace Persistence.Validation
{
public class ValidationEventListener : IPreInsertEventListener, IPreUpdateEventListener
{
public bool OnPreInsert(NHibernate.Event.PreInsertEvent #event)
{
var entityToInsert = #event.Entity as IBusinessBase;
if (entityToInsert != null)
{
if (entityToInsert.BrokenRules != null)
{
RollbackTransactionBecauseTheEntityHasBrokenRules();
}
}
return false;
}
public bool OnPreUpdate(NHibernate.Event.PreUpdateEvent #event)
{
var entityToUpdate = #event.Entity as IBusinessBase;
if (entityToUpdate != null)
{
if (entityToUpdate.BrokenRules != null)
{
RollbackTransactionBecauseTheEntityHasBrokenRules();
}
}
return false;
}
private void RollbackTransactionBecauseTheEntityHasBrokenRules()
{
try
{
ISession session = SessionBuilderFactory.GetBuilder().CurrentSession;
if (session != null)
{
session.Transaction.Rollback();
}
}
catch (Exception ex)
{
//this will force a rollback if we don't have a session bound to the current context
throw new NotImplementedException();
}
}
}
}
I would say this matters on your architecture. With MVC apps that I have done in the past we abstract away the domain stuff away from the web stuff and naturally we use dependency injection to avoid hard dependencies.
When it comes to validating the model when you are in the act of binding it, yes you could easily use the service, repository, or whatever you have next in your architecture in a ValidateSelf method. I think the question rises of what about that dependency.
If I remember correctly you can create your own custom binder that will use your dependency injection framework to plug-in any services your model needs for validation when you create it, call MVC's default binder to fill in the object, then call into Castle Validation's framework to do the validation. This isn't a fully thought solution, but hopefully it provokes some ideas.

Resources