As a new WPF programer I cant find the difference between two different way to validate user input:
What are the pros and cons of writing custom validation rule against implementing IDataErrorInfo, and vice versa? WhenShould I prefer one over the other?
Update:
Though I got my answer already, I found related article that may help others.
Basically, if you implement IDataErrorInfo, validation is implemented in the bound object, whereas if you implement validation rules, validation is implemented in objects attached to the binding.
Personally, if you're using MVVM, I think you'd have to be crazy to ever use anything except IDataErrorInfo. You want validation to live in the view model. If it's in your view model, it's centralized and it's testable. If it's in your view, then your validation logic can be wrong, or missing, and the only way to find it is by manually testing your view. That's a huge potential source of avoidable bugs.
There are places where it makes sense to use validation rules - if, for instance, you're building a UI around dumb objects (an XmlDataSource, for example). But for most production applications, I wouldn't go near it.
IDataErrorInfo
Validation logic keep in view model and easy to implement and maintain
Full control over all fields in the viewmodel
Validation Rule
Maintains the validation rule in separate class
Increase re-usability. For example you can implement required field
validations class reuse it throughout the application.
My opinion is, for common validation like required field validations, email address validattions you can use validation rule. If you need to do custom validations like range validations , or whatever custom validation use IDataerrorinfo.
You implement IDataErrorInfo to be able to use databinding with eas. You still build your custom validation rules.
Related
In my MVVM based application I need to validate fields in a data entry from. If possible, I would like to use the standard WPF validation binding with ErrorTemplates.
However I would like the execution of the validation logic to be completely driven/triggered by the ViewModel (push to the View, not pull by the View) for the following reasons:
It must work asynchronously because validation logic might take a while to execute.
I need to be more deterministic and fine grained when validation logic is to be executed (e.g. only after the user clicks "Apply" or when the internal state changed in a way that entries suddenly become invalid)
I know Silverlight has INotifyDataErrorInfo which was introduced for exactly this purpose, but WPF doesn't. How can I still have my validation logic exectuted deterministically and asynchronously?
I posted an answer on your other question that apparently answered this one too.
Create a visualtree off of a control template in code
The built in validation for WPF and Silverlight is meant for quick client-side validation (such as Regex, parsing values, etc.).
If you need to go to a server to perform validation (or validation takes a long time), I would do that in a custom way. Such as when clicking a save button, etc.
So say you have a Save method in a ViewModel (you don't mention which MVVM framework you use):
public void Save()
{
//Do your validation, this might start a new thread (I use Async CTP myself)
//If validation is good, do your extra work, else display validation errors
}
I would just do all the work required for this within an action in your ViewModel
I have a list of business objects (1000+) with 50 or so properties they have around 70 different validations that need to be performed. It seems like the way to go is to use a validation rule, but I really like IDataErrorInfo. Is it a waste of memory to have IDataErrorInfo defined for every object while they use the same validation all along?
PS: I didn't post the code because it enormous and tedious to look at.
IDataErrorInfo just contains a pair of properties.
It has no per-instance overhead.
It's up to you to make an implementation that peforms well; the shouldn't be too hard.
I am a big fan of extending the built in ValidationRule class and using it directly in bindings, as opposed to using IDataErrorInfo.
Check my blog post here, see if it helps: Taking data binding, validation and MVVM to the next level - part 1. This concentrates on how to use it for validating a TextBox, but the exact same thing applies to any bindable element, i.e. columns on a DataGrid. The advantages it gives you is you can keep the validation code out of your viewmodel and model (if you are using that sort of pattern), the validation is reusable anywhere, and you can be quite granular with which validations are applied and where.
When looking up tutorials for the best practices to do property validation in WPF MVVM I see a lot of people use the interface IDataErrorInfo I was just wondering if it is possible to setup automatic validation like that used in ASP .Net MVC using attributes?
Can anyone sugest what the best practices are for model validation in MVVM? Should the validation be on the base model class? or on the view model class?
Silverlight has a control called the DataForm that works using the DataAnnotations Attributes and someone was kind enough to port that control to WPF. I believe that is something along the lines of what you're looking for.
These are good questions!! Validation belongs in BOTH the Model and the ViewModel(s). Here is how I usually approach it:
First I put as much validation in the Model as I can - these will be rules that are independent of a given presentation. For example, assume an employee in your domain is not valid if it doesn't have a EmployeeNumber property that is not null, and six characters in length, and each of the six characters must be a digit.
Secondly, I have a base ViewModel class that implements IDataErrorInfo. In this base class I basically ask the Model if it is valid, triggering an error if it isn't (which is easy to translate to the View by virtue of IDataErrorInfo). I also make the implementing methods of IDataError info virtual, because...
Lastly, there will be edge cases unique to a given presentation that cannot be captured by the Model. For a (contrived) example, assume you have one presentation in which an employee is valid if only his first and last name are entered, and another that requires a middle initial as well. While you certainly can and should have a FullName component / valueObject property in Employee to validate that the property is not null, you need a subclassed ViewModel for each presentation to know if the user entries for the properties of the Fullame are valid in this case.
Finally, you can and should use a Validator for your Model validation - I like NHibernateValidator but there are certainly other (very) good ones available. Most of them, including NHibernate's, will support the attribute validation you are looking for. I prefer a cleaner alternative to attributes however, whereby I setup all validation rules for my validator in a separate project (ie, MyDomainImpl). Cleaner in the sense of less noise in the Model, and a cleaner separation of concerns.
Feel free to ask questions if you need to Also give yourself some time to work thru this until you have an approach that works for you - this is not a trivial topic.
HTH,
Berryl
My take is that validation should be on ViewModel and not on Model because :
Validations are for incorrect input
and the first logical point of UI is
ViewModel. It is good practice to
validate and stop request at
ViewModel and not send across invalid
data to the Model
Also many a times Models are legacy and the assumption is that they
cannot be modified. ViewModel creates
a good wrapper over the model.
If you are using any Dependency Injection tool for your aplication like Unity, Windsor Castle etc., you can use interceptors to validate ViewModels. Interceptors are invoked first before any call to ViewModel methods.
An example of using interceptor with Castle can be found here -
http://www.castleproject.org/container/documentation/trunk/usersguide/interceptors.html
Where to put the validation logic?
Software systems mostly need some kind
of validation to ensure that the
business logic has to deal with
correct data only. These validation
rules are defined by the business
model and so the Domain layer is the
right place to implement them. Just
keep in mind that you don’t start to
duplicate the validation code between
the business objects.
link
.
You might be interested in the sample applications of the WPF Application Framework (WAF). They show how to use the .NET DataAnnotations validation attributes together with the MVVM pattern.
A common MVVM/WPF approach is to data-bind the UI's controls directly to the underlying model object. The model object may contain its own validation logic (perhaps exposed via IDataErrorInfo) or may be validated by a helper class checks a model object instance for errors. In either case, at times the model have invalid data in it and so be in an invalid state.
However, in the DDD world, the model is never to be in an invalid state. How do you suggest performing validation when using WPF and DDD?
Thanks,
Ben
I don't think the View in MVVM should be binding directly to the domain model, it really should be binding to a View Model instead. Then the View Model can be in an "invalid" state which can be reflected through IDataErrorInfo. Only later when a user operation (e.g. Save, OK, Apply) applies this to the underlying domain model should the domain model enforce validity, you can also prevent the apply by not allowing the operation in the UI.
Although I must say I've found that it's not always easy to do this without duplicating the validation logic to some extent.
I'm tending to think that a facade or similar layer should be used as the MVVM "model." This facade can be in an invalid state (unlike the DDD model). For validation, it can either contain its own logic or a tool like FluentValidation can be used. Once it is in a valid state, its "do action" function can be called. This will pass the data in the facade to the underlying DDD model. With this approach, at no point does the DDD model encounter invalid data.
With this approach, the facade and its validation logic could be used by multiple view/view model pairs, eliminating the validation logic duplication present when each view model does its own validation.
Validation belongs in your business logic (domain model). I suggest taking a look at FluentValidation for .NET.
I've actually had good luck having the ViewModel setter call the underlying Model object, and letting FluentValidation throw an exception. If you're using a WPF TextBox, the binding will keep working, but the TextBox will show a red outline (assuming you've used the syntax where the TextBox updates the ViewModel on each and every keystroke). Just don't throw an exception in the getter or you'll break the binding.
It's better to route all your communication from the ViewModel to the Model through some intermediary (I introduced a Presenter, but this can be as simple as passing the Model operation as a lambda to a callback on some mediator). When an exception happens while operating on the Model, the Presenter catches the exception and displays a friendly message to the user with the details from the exception. FluentValidation produces really nice default error messages for this purpose.
What technique or library do you recommend for on-screen validation. That is, validation that is very visible to the user.
My requirements:
The validation must have a way to indicate to the user which fields have a problem.
The validation must have a way to indicate to the user how to fix the problem.
The validation must support comparatives like TextboxA > Textbox B.
The validation must support custom logic like "If CheckBoxC is checked, ListBoxD must be empty".
Sometimes, though not always, the user can save a record even though validation fails.
A combination of using IDataErrorInfo and ValidationRules should meet all of your criteria.
1 & 2 - can be handled easily using the standard WPF validation display techniques. For background info, I'd read Josh Smith's MSDN article, in particular, he shows a couple of ways to handle displaying validation information.
3 & 4 - can be handled easily via IDataErrorInfo. This interface lets you do any logic required in order to display validation, and can combine multiple properties in the validation rules.
5 - This is a matter of just tracking which rules prevent saving, and which do not. You'll need to handle this directly, but again, IDataErrorInfo can help here, since you can use a known set that allow saving, and have every other issue prevent it.
For simple cases, Validation Rules make life easy. They can be combined with IDataErrorInfo, however, for a nice mix of simple with extended logic for difficult cases.
You might find the BookLibrary and EmailClient sample applications of the WPF Application Framework (WAF) interesting. They use the IDataErrorInfo interface in combination with the .NET DataAnnotations attributes to define the validation rules.