Validating Business Rules in MVVM

I’ve always thought that raw data validation should occur in the data Model, while Business Rule validation should occur in the ViewModel.

For example, verifying that a UserName is no longer than X length long should occur in the data model, while verifying that the UserName is unique would occur in the ViewModel. The reason for this is that the User Model is simply a raw data object. It doesn’t contain any advanced functionality like database connectivity, or knowing about other User objects. It’s a selfish little thing which only cares about it’s own data.

Since I use IDataErrorInfo for my validation and like to expose the entire Model to the View from my ViewModel, this presents a problem. Using the above example, I could bind a TextBox to SelectedUser.UserName, and it would automatically show an ErrorTemplate if the string was too long, however it wouldn’t show an error template if the UserName already exists.

After some thought, I decided to add a Validation Delegate to my Models to solve this problem. This is a delegate which ViewModels can use to add Business Logic Validation to its Models.

The idea is that your Models should only contain raw data, therefore they should only validate raw data. This can include validating things like maximum lengths, required fields, and allowed characters. Business Logic, which includes business rules, should be validated in the ViewModel, and by exposing a Validation Delegate that they can subscribe to, this can happen.

Rate this:

Share this:

Like this:

LikeLoading...

Related

This entry was posted on Sunday, January 22nd, 2012 at 6:35 pm and is filed under MVVM. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

I thought about writing something for basic validation with IDataErrorInfo, but it seems like there’s already so much good material out there so I doubt I’d add anything new. Perhaps I will one day anyways for completeness.

I guess my perspective would have been to put as much validation in the Model as possible. In the app I’ve been writing, I’m expecting the Model to be accessed from several different ViewModels (and therefore several different Views as well). Thus, I would be facing a lot of validation code duplication if I put such validation code in the VM. Thoughts?

I’ve always thought of models as just dumb data objects, so they should only perform raw data validation, such as required values, string length, or min/max values. Any kind of business validation should be inside the ViewModel to keep the layers separated.

I disagree with this because it suggests that your business rules only apply to data modified via the user interface.

What if you have web services that allow other systems to interact with your model, bypassing the user interface altogether? Or batch processing? Or a set of unit tests that need to exercise the model and can’t interact with the UI?

Your business rules belong in the model to ensure that your data is always in a valid state regardless of how it was manipulated.

That’s not to say that the logic needs to reside in your “dumb” data objects. It could be a second layer within your model that controls access to your data objects — ensuring that your data is always in a state that doesn’t violate your business rules regardless of the source of these changes. Think of your model as BOTH the data and rules that govern it.

The ViewModel should just be a neat package of the model objects that are needed for your view.

You bring up a good point about other UI interfaces that use the Model other than ViewModels. At the time of writing this, I was thinking of simple MVVM applications with very few layers, however if I did have a larger application infrastructure then I would definitely be sure to check the business logic on whatever layer is responsible to actually saving the data to the database, such as a web service layer, in addition to the UI layer.

I dislike putting business logic directly on the model object because the rules might be different depending on the context in which the model is used. For example, the same model might be used from an administrative screen as the one that is used from a user screen, and the business rules validating the data may be very different for the two scenarios.

In a perfect world I’d like to validate the data from both the UI side and from the web service side, and the code posted here allows me to do that. This way I don’t have to wait for the web service call to validate the data, and I don’t have to rely on the UI side to validate data before saving. It all depends on how your application is structured :)

Roger’s point brings up an important abstraction called ServiceLayer. We used this in our project effectively.

Whenever ViewModel needed access to the model, we routed it through ServiceLayer.

We needed a concept called ServiceLayer for many different reasons

For example, assume that when the user clicks on a button named “Save”, we need to save data in one table and send a mail. Somewhere in application, this sequence has to be specificed (call to data accesss layer to save, call to mailsender class to send a mail).