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.
Related
I known there are several existing questions about whether to implement INPC on the model, most arguments are about code repetition because of property proxies, which will be not a concern in this case, because the Model and the ViewModel will be autogenerated by a tool, so any code-size arguments is invalid.
There are any drawbacks in not implementing INotifyPropertyChanged on the Model besides code size?
Also, the generated Model will be used directly by the programmers but the ViewModel will only be used by other generated code, so the size and complexity of the view model will be hidden, but the Model has to be as simple as possible without losing functionality, in this case Is better to implement validation and calculated properties on the model or in the view model?
Consider that the model may be or not database entities.
Thanks
This is too generic a question to be answered.
"Is better to implement ... ?" : This depends on the application need . Ideally the Model has all the properties and the Viewmodel is just the place where you fill the Model and write the necessary business logic.
Since you are talking about autogeneration, i suppose you have written some util which does this creation. Ideally the validation should be present in both Model and ViewModel. Model side validations are supposed to check any DB/server side validation if present and the ViewModel(VM) is supposed to validate the client for eg: In VM you validate for whether a property is greater than some other property, but in the Model validation you would validate for uniqness or null etc.
Other thing is the calculated properties(I hope this means calculation done in the database and filled in a property), these properties ideally should reside on the ViewModel .
Hope this answers your question.
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.
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.
I often hear a Model must be wrapped by a ViewModel that the View is not coupled to the Model/not aware of it.
With MVC it is common to bind the View to the Model... nobody complains so what ?
I am frightened of creating all that wrappers and doing nearly only duplicating property stuff.
In some cases you don't need to, just as you don't need properties in many cases but can get away with public fields.
But your model should mirror the domain structure and logic, while a view model mirrors the UI structure and logic. At least, as far as I understood it. Those two are not necessarily the same and each one can change independently from the other.
You should always apply a pattern to your individual problem, and modify it in areas where it does not apply. Just because the pattern implies the usage of a view-model, doesn't mean you necessarily need a view-model in every scenario. In the case that your model exposes all of the needed properties and no further abstraction is needed, maybe a view-model is unnecessary.
However, in many cases the view-model will eventually be of great use and far easier to maintain than adding extra properties to the model. Consider this carefully before binding directly to the model.
The ViewModel is used to only pass the data that you really need to a view.
When you use the model, instead of the viewmodel it is possible that you use data that came directly from the database.
When using the model the wrong way, it is possible to edit data in the database that you don't want to edit.
It is safer to use a ViewModel.
One point which didn't seem to come up (directly) yet is that ViewModel can easily support data that should never even be in the model such as the text typed in the search text box or selected list items in case these values are needed in commands or further data bindings and passing them as parameters every time seems like too much trouble.
But as stated already, if you are confident that all the data you need is already available in the Model, go ahead and do away with the ViewModel.
One common scenario where ViewModels come in very handy is when Enum values should be displayed. In my eyes, a ViewModel is the perfect place to convert Enum values to user-friendly representations. You could even introduce a localization step in your ViewModel.
Furthermore, ViewModels can simplify some other scenarios. However, as you said, they can also duplicate a lot of code. That said, you could create a ViewModel with a Model property which allows to bind directly to the properties of the Model class. Now if you later realize that you need some conversion step, you can still add that property to the ViewModel and bind to that property.
But I think in most cases it makes sense to use a ViewModel from the beginning because it might be hard to introduce it in a later development stage.
There is no problem binding directly to a Model from your View where possible.
What you will find though is very quickly you run into a situation where you need to model things your view needs that aren't in your Model.
Given you never want to corrupt your Model with View concerns, you are left with no choice but to create a ViewModel.
It depends on may indicators: e.g. if your model is provided by EF there's no point in exposing it to your View - why the heck the View would need all model's method/properties and tons of stuff (not mentioning data security) But if your model is really simple and you feel, that you're not going to expand/change it much by and VM, there's nothing on the way to use it just like that :)
You might as well ask, "What's wrong with putting all the functionality of my program into one giant class?" On the one hand, there's nothing wrong; it can be made to work. On the other hand, everything is wrong: if your program is one big ball of wire, you have to straighten all of it out in order to change any of it.
Look at a Windows Forms programmer written by a beginner. You'll find all of the business logic in the buttons' Click event handlers. What's wrong with that? Don't you want that logic to be executed when the user clicks the button?
This is essentially what you're proposing doing within the world of WPF. Will it work? Sure. For trivial projects, it may even work well. You're accumulating technical debt, though, and when the time comes, you'll have to pay it off by refactoring your code into something manageable.
We're just getting into MVVM in WPF.
We have implemented our ViewModels with 'strongly typed' properties (int, double? etc.) that we bind to in the view.
Type conversion works OK, mostly, and so entering data is simple enough. But we run into problems with validation.
If, say, a non-numeric value is entered in a text box bound to a numeric property, the conversion fails, the property is never set, and we never get a chance to provide proper feedback to the user. Worse, the property retains its current value, leading to a mismatch between what's displayed in the view and what's actually in the ViewModel.
All this can be handled with value converters, I know. But I have seen several opinions to the effect that conversion should not be the view's responsibility at all. What is entered in the view are strings, and the conversion, validation etc. should be the ViewModel's responsibility (so the argument goes).
If so, we should rewrite most of the properties on our ViewModels to string, and provide error information through the IErrorInfo interface, for example. It would surely make for simpler, leaner XAML in the view. On the other hand, conversion, validation etc. will be less declarative, explicit and flexible, from the point of view of the View designer.
It seems to us these two approaches are fundamentally different, so before we decide, we'd like some informed SO opinions on the matter.
So: should ViewModels expose a simplified, 'text-based' interface to the view and handle conversion internally? Or should ViewModel properties expose the actual data types, leaving such chores to the view to handle?
Update:
Hard to pick a winner here, but I finally landed on one of you who concludes more or less like myself.
Specifically, we have decided to keep the ViewModel properties typed. The main reason for this is the flexibility it affords us in the design of the view, and the power of explicit, declarative conversion/formatting in XAML.
I noticed an assumption with you who will disagree with us in this, that the design of the view is fixed and ready. Hence, no decisions about conversion, formatting etc. need be made in the view. But ours is an agile process, and we haven't got all the nitty gritty detail of the UI figured out on beforehand.
In fact, leaving the details of the UI to be worked out along the way leaves room for creativity and besides, in my opinion, even a meticulously worked out design will always end up morphing throughout the implementation process.
The point of all this is that whereas business rules enforcement certainly belongs in the ViewModel, it seems to us that simple conversion and formatting is a view-thing. It may sound like heresy, but I don't actually think type conversion in the view needs unit testing at all (so long av we unit test the actual type converters).
All in all a great discussion, folks, with well formulated, informed opinions. Thanks.
This is a very interesting question and one that I don't feel has a definitive answer, but I'll do my best to throw my thoughts out there.
Looking at the MVVM pattern as I understand it, the point of the ViewModel is to expose the data in a way the View can understand without any assumptions about the way the view is going to use it. For an example let's pretend that we are modelling the speed of a car:
public class CarModel
{
public int MilesPerHour { get; set; }
}
public class CarViewModel
{
private CarModel _model;
public int MilesPerHour
{
get { return _model.MilesPerHour; }
set { _model.MilesPerHour = value; }
}
}
In the example above I've exposed the property as an int since that is what it is in the model. The disadvantages of this you have listed in your question, but the main advantage is that it gives the creator of the view a valuable piece of information about how to display that data. Remember that we (as the authors of the ViewModel) don't know what the View looks like. By committing to the idea of the data being an int the View can use a textbox or some other control that only accepts numbers (a dial, for example) to display the information. If we say that we are going to format the data in a way that we assume is helpful to the View it takes that important power away from it.
On the other hand we work in real world. We tend to know what the view is. We rarely plug and play different views on top of the same ViewModel and adding the conversion code into the ViewModel is simply easier. I don't think it is right, but that doesn't mean you won't find my production code using it...
Finally (and I'm sure you know this, but for completions sake...) business logic should be done in the ViewModel. If we decide that the car shouldn't go above 70mph then it isn't the responsibility of the view to enforce that. So you'll still end up with some kind of error provider, but at a business rather than display level.
Okay, maybe that wasn't finally....
I wanted to address the comments made by Kent, and my thoughts didn't fit into a comment.
Obviously the primary difference between my and Kent's point of view (as I understand it) is he reads ViewModel to be a Model of the View and I read it to be the thing that exposes the Model to the View. A subtle difference I'll admit, but I think the upshot is that I don't want to remove information that the model provides, even if it makes it easier for the specific view I'm using.
My point of view is based on the assumption that you should be able to swap views out, they should be fleeting things that may change depending on the requirements of screen size, hardware, platform, latency and environment. The interesting twist is that I have never actually needed this functionality, nor seen anything (beyond proof of concept applications) that have ever used it, but if we accept that we won't use it now or at any point in the future, and that each ViewModel will work with one, and only one, View then we may as well go back to putting all the code in the code-behind file and throw the ViewModel out completely - after all, it's so tightly coupled that it may as well be the same class.
Ideally I would like a situation where the ViewModel can say "this value is an int, it will always be an int, and you can display it in anyway that you like. But you can give anything back to me and I'll do my best to make it fit, and if I can't I'll let you know". Basically my MilesPerHour property should have an int getter, but an object setter. That way the views keep all the information I feel they need, but don't have to worry about conversions or validation.
Absolutely it belongs in the view model, for all the usual reasons, including:
Designers own the XAML. Do you want the designers to have to understand and implement the requisite type conversion and validation logic?
Testability. Don't you want to validate that your conversion and validation logic is working correctly? It's much harder if it's embedded in the view.
On the other hand, conversion, validation etc. will be less declarative, explicit and flexible, from the point of view of the View designer
I think this is a moot point because the view designer should be responsible for these things. The designer is trying to make the UI look and feel a certain way; it is the developer who implements the business logic, including conversion and validation logic.
Should the MVVM ViewModel perform type
conversion/validation?
Yes.
The view model is an abstraction layer between the view and the model - the perfect spot to perform any type conversions (instead of cumbersome value converters). Validation should absolutely occur as part of the view model.
We use our View Model to handle the conversions as much as possible for data types. This reduces the need for a value converter to some very specific circumstances. You want to expose whatever type is easiest for the view to consume. This has been working well.
The one specific question you raised:
If, say, a non-numeric value is
entered in a text box bound to a
numeric property, the conversion
fails, the property is never set, and
we never get a chance to provide
proper feedback to the user. Worse,
the property retains its current
value, leading to a mismatch between
what's displayed in the view and
what's actually in the ViewModel.
might be handled by exposing your view model type as a nullable type. This should still allow the underlying source to be updated, even if invalid data is entered, and trigger validation. This worked in a similar situation we had with DateTime and a date time picker.
Keep the view as dumb. We don't have official designers, our developers are our designers, so keeping the view dumb has some benefits:
We (developers) get to keep our sanity (XAML is somewhat less verbose)
Business logic (including validation) stays in the view model and can enable testing
Good Luck!
-Z
This is a good question, and I can certainly see both sides of the discussion.
My thought is that what you're really looking for is a proper NumericInputControl that you can use in your xaml. This will provide a better user experience because your users won't be able to accidentally enter text in a number field and, because the control constrains input without validating it, you can maintain the more strongly-typed ViewModel.
I'm not sure how you'd want to go about implementing one, I know that the classic spinner/NumericUpDown controls are falling out of favor because they aren't touch-friendly, but I don't believe that the introduction of such a control will violate the purity of the design approach or your ViewModels. You'll receive a number that you can then range-validate in the appropriate place, supply feedback via IDataErrorInfo as usual, and so forth. :) This technique lets you get the best of both worlds without any real drawbacks (except the creation of a numeric control).
Or should ViewModel properties expose the actual data types, leaving such chores to the view to handle?
Conversion and templates are done in View, because they both are just a conversion of values, models and viewmodels into controls! Controls are available only inside View.
Validation is done in ViewModel, because validation is done according to business rules and can even be done through a call to a remote service. View knows nothing about business rules, but knows how to present validation results.
If, say, a non-numeric value is entered in a text box bound to a numeric property
A properly crafted numeric text box control never allows user to input a non-numeric value.