IDataErrorInfo vs ValidationRule vs Exception
Asked Answered
H

4

25

Can anyone tell me which is a better approach for Validation in WPF.

  1. Implementing IDataErrorInfo
  2. Creating ValidationRule
  3. Throwing Exceptions

in terms of performance, memory leaks, code maintainability and re-use.

Haemostat answered 5/6, 2010 at 15:3 Comment(0)
H
28

This is kind of a complex request, and honestly it'll probably vary based on preference more than anything else. But, here's my understanding:

  • Performance: Exceptions will lose nearly every time unless your other implementations are horrendous. There's significant overhead to the throw/catch cycle. (Anecdote: I had a 'must be a number' check that was an exception, it "lagged" the UI for a noticeable time when it failed, but when converted to a ValidationRule it was effectively instant.)
  • Memory leaks: This depends on how your validation rules or IDataErrorInfo implementations are done.
  • Code maintanability, reuse: This is the interesting part, of course. What you really should be asking is "when is it appropriate to use a ValidationRule instead of IDataErrorInfo or vice versa?"

ValidationRules are older than IDataErrorInfo (I believe the latter was introduced in .Net 3.5). Based on this alone, it would seem that the WPF team prefers IDataErrorInfo. But the truth is they're built for different things. If you have MVVM or an equivalent pattern, IDataErrorInfo is superior for errors in the model (like, say, a negative age) whereas ValidationRules are superior for errors in the view (say, an age of ☃). It's of course possible to have the ValidationRules perform "business logic" checks, or to have the IDataErrorInfo tell you "a unicode snowman is not a valid age", but you'll (probably) get the best maintainability by keeping to this pattern.

But don't use exceptions for validation beyond the initial testing to see what exact conditions you should be testing for.

Hautegaronne answered 6/6, 2010 at 0:27 Comment(3)
Today was reading up on IDataErrorInfo - seems it is older than ValidationRule - seems like the IDataErrorInfo interface has been around since Framework 1.1 (msdn.microsoft.com/en-us/library/…) but ValidationRule since Framework 3.0. Don't think it fundamentally changes your answer thoughTrihedron
it appears to me that the ValidationRule can intercept the Binding process and perform the validation even before the property is set. While the IDataErrorInfo or INotifyDataErrorInfo requires the property to be set successfully (which passes the binding process). In simple cases such as validation for an entered text being a number. I could not find any way for the IDataErrorInfo and INotifyDataErrorInfo to work in this case, because the property will never be set if the entered text is not a number (convertible to some number type in the model), so looks like only ValidationRule worksAmeliorate
@Ameliorate When using ValidationRule, it will also intercept the binding process if property is set programmatically from code (view model) instead of UI?Markmarkdown
U
8

It is not good idea to use exception for error handling. Using exception will reduce performance. It is a matter of selecting and Implementing IDataErrorInfo or Creating ValidationRule.

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.

Ungrateful answered 30/9, 2013 at 3:42 Comment(0)
O
8

I have a slightly different take on the topic, than the views presented in the other two answers:

ValidationRule

  • This is appropriate for validation that needs to be done before the source of a binding is updated. Reasons you might like to do this include being able to present a specific error message to the user, especially messages that relate to values before data conversion, or validating data that has to be converted.

  • As noted in other answers, it's also somewhat easier to share validation among multiple controls, as you can do things like create a single ValidationRule which is used in multiple bindings, or use a BindingGroup to provide a single ValidationRule that checks multiple bindings at once.

IDataErrorInfo or INotifyDataErrorInfo

  • This puts validation into the view model, and is appropriate for scenarios where it is allowable for an illegal value to be stored in the view model. Specific error messages can be provided to the user via this interface.

  • Validation is available for any client of the view model implementation, providing better reuse for such validation.

  • Reuse of validation rules is somewhat less convenient, but not impossible by any means. You just need to implement your own helper methods or objects to perform the validation as you like.

Exceptions

  • The other answers eschew exceptions for validation, based on performance concerns. However, it's been my experience that exception handling in UI scenarios is generally just fine. In spite of the extra overhead of exception handling, it still happens way faster than the user is capable of noticing (unverified "anecdotes" notwithstanding).

  • One important aspect of exceptions is that it gives you much of the benefit of implementing an error-notification interface on your view model, while still preventing invalid values from being set on the view model properties. In other words, you may have validation scenarios where ValidationRule happens too early and IDataErrorInfo happens too late. Throwing exceptions from property setters would address those scenarios.

Bottom line: each validation technique has its own pros and cons, and is appropriate for specific scenarios. None are uniformly superior to any of the others. It depends a lot on what kind of validation you are trying to do, and where you want to see that logic executed.

Orgeat answered 20/4, 2020 at 6:4 Comment(0)
H
0

ValidationRule has several advantages over IDataErrorInfo:

  • It follows the Single Responsibility Principle (SRP) since its single purpose is to perform validation. The validation logic is contained within its own ValidationRule class.
  • ValidationRules can be developed naturally using Test Driven Development (TDD).
  • ValidationRules once developed are reusable and can be applied to multiple binding targets in XAML.
  • ValidationRules are explicit; they must be specified in XAML which can make the XAML verbose.

With IDataErrorInfo, all validation logic for properties of a view model is contained within the property indexer, which can become a very large switch statement and hard to maintain. The view model's validation logic can still be unit-tested, but this is unit-testing after the validation code has been written, not TDD.

View models that implement IDataErrorInfo seem to brake the SRP. With additional responsibility of doing validation, they have more than one reason to change. Furthermore, different view models may require the same validation (for example, must be a positive number), and each view model will have the same validation code repeated, which breaks the Do not Repeat Yourself principle (DRY).

Helvetic answered 22/7, 2022 at 16:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.