In a typical MVC application we have validation that occurs in many different places. It might be client-side, in the controller, and then again at the data level. If you have a business layer, then there is additional validation there as well.
How do we unify all these so that we're not violating DRY, and causing support nightmares when validations change? A sub-question is how to enable dynamic validation based on the model across all layers.
For example: We may have a ViewModel that has data annotation attributes. In MVC2/3 this unifies client-side and controller validation, but does not help with the data model (unless you are using your data model as your view model, which isn't a good practice).
This means you have to add the same validations to the data model and business layers, duplicating it. What's more, the data model might have subtly different validation requirements than the view model (for instance, an entire data record might comprise several view models of a multi-step wizard. And only a complete record can be saved).
Some people add complex validation to the data model when using an ORM like EF or L2S with partial classes, which i'm not sure is the right path either. It works for apps that are primarily data oriented (data entry type apps), but would not work for apps that have more non-data business logic.
What I'd like is some way to either generate validation for all layers, or a way to hook into a single validation system. Does anything like that exist?
"Fluent Validation" provides better re-usability.
Please visit.
http://fluentvalidation.codeplex.com/
Re-usable documents for Fluent Validation.
http://fluentvalidation.codeplex.com/wikipage?title=CreatingAValidator&referringTitle=Documentation&ANCHOR#ReusingValidators
http://fluentvalidation.codeplex.com/wikipage?title=CreatingAValidator&referringTitle=Documentation&ANCHOR#Collections
Below one may be full fill your needs.
http://tnvalidate.codeplex.com/
I guess I really don't understand your answer since rarely is your data model, business model, and view model all the same. If they are, just use the data model and put the validation on it. The validations across all your layers are specific to the layer.
Example: Your ui should not contain business layer logic in case you ever change the ui layer, or create a new one.
Related
It is common sense to keep business logic out of controllers. It is also common sense that database access logic should be on a repository, using a repository pattern, as described here: Repository Pattern
However, the repository pattern specifies only very simple low level database operations: Insert, Delete, Update, Select. People advise to keep validation logic out of it too. That is not a problem, since most of the validation can be put inside the model object itself. The problem comes when we need to make some kind of cross-validation, that is, a validation that needs to look on more than one instance of the same model object (for example, ensuring that a name is unique accross all instances of same object) or, even worse, when the validation logic needs to check two or more objects of different types. In this case, we have a real big hole: the business logic cannot be in controller, cannot be in the repository, cannot be in the object model itself (since the logic is not bound only to the object's properties). Where should this logic be? What is the best design pattern for this kind of requirement?
You can create a service layer as described here:
http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs
The problem here is that your design requires the UI to do validation based on business concerns.
The way to accomplish this is to abstract the validation into the business layer. Your business layer may have methods like ValidateUserIsUnique() and then your ui calls into this layer and receives a result, which is then used for validation.
In particular, for client-side validation MVC provides the RemoteValidationAttribute, but this will only do client-side validation. You will also need to do a server-side validation that calls the same (or a similar) function on the server.
A typical EF+MVC system will have two or three levels of validation:
For ViewModel: input / physical validation (DataAnnotations, FluentValidation), in other words, length, null, range, regex, etc.
For Model: input / physical validation (repeat of 1 in case MVC is not used and data comes from another system, WCF, forms, etc.)
For Model: logical / "business rules" validation
I can't find best practices for validation of 2+3 for the actual Model / entities / domain / "business rules". We either:
put simple validation rules in an entity's property setter (but this is really messy)
hook into EF's SaveChanges(), and if an entity is in the Added or Modified state then trigger validation (which validates the entire entity at once)
This is hard to maintain. A lot of thought went into ViewModel validation, but for Model validation it is domain-specific and so it is for you to determine a creative solution, and mine is not that great.
Are there better ways to do this, or helpful tools (like maybe DataAnnotations or FluentValidation but for domain entities)?
Where is the best place to do model validation or to trigger the model's validation?
A typical MVC+EF system will have 3 layers, but they aren't what you're talking about.
Presentation Layer (input/output)
Business Layer (Logical layer)
Data Layer (model represents low-level data)
MVC provides validation for layer 1. EF provides validation for layer 3. There is no validation functionality provided by either MVC or EF for layer 2. If you want validation there, you have to do it yourself, or use a third party business object framework.
Validation in layers 1 and 3 are separate, even though in many cases they may have similar validation. The reason is that validation is accomplished in different ways, and with different requirements.
For example, you may have a field in your database that is nullable for data modeling or business logic reasons (let's say some data is pre-loaded and the user is required to update the field as part of the business process). The data layer says it's nullable, but you want your UI to make it required.
EDIT:
Simply put, the Data model should not be enforcing business rules. Therefore, you should not need any validation in the data model, other than to validate against the physical data model (ie, if the field is nullable, the data type in the model should nullable, otherwise not). In most cases, you physically cannot insert invalid (from the data models perspective) data because the code model will not allow it. The only exception to this is string variables, which can obviously overflow the size constraints of the physical model, but if that happens then an exception gets thrown anyways.
Your middle tier, the business layer, should be where you need to validate business rules (for example, that a customer purchase order must start with a letter). Neither MVC or Entity Framework, or WCF or whatever provide any way to do this validation.
There is a bit of a disconnect here, because the business rules should (in theory) drive the presentation layer validation. But, MVC has no built-in functionality to do that, though. So you end up duplicating your business rules in the UI.
There is at least one third party business object framework that tries to deal with this. CSLA. They provide a custom MVC model binder that ties in the business objects with the UI to do validation, but this is just using the built-in extendibility of MVC to do this.
So, if you don't want to use a dedicated business object framework, you are stuck either duplicating validation between UI and Business layer, or trying to figure out your own way to make your own business layer control UI validation.
We say that model validation at controllers layer is the correct place to validate all data we gonna operate with. In this case, if we change UI to another (remembering that our layers must be pretty decoupled) the new data validation principles are going to execute - in this case all our inner rules can be violated.
You may say that data models is the separate layer and that layer, but not UI, is the only place for validation. But in this case i found it more effective to validate data in the service or business objects layer, don't i?
In fact we have a number of objects corresponding to our domain object: db table record, linq2sql class, domain object class, viewmodel class. Should it be only one place to validate data model? Why should it be in (or close to) UI but not in the other layer? In my opinion, the validation must occur in the service layer - with all other busness logic. If i need to inform user about error as fast as possible, i'll use client validation in addition to main one. Thoughts? Thank you.
Data validation is the responsibility of the model. The best place to put validation rules in my opinion is as constraints in the database. Having constraints ensures that no incorrect data will ever be stored in the database, no matter how it is access. Unfortunately only basic constraints are suitable to express in the database.
The next place to put validation, when using linq-to-sql for data access, I is the extension methods on the entity classes. Then all code will have to pass through the validation.
To improve user experience, basic validation can be repeated in the UI, but that is just for user experience and to catch the most common mistakes early. On the web, using JavaScript validation is preferable. On rich clients the same code as the one called by the extension methods can sometimes be reused.
Always remember that any service exposed to a client, could be called by a malicious client that lacks the validation that the real client does. Never trust the client to do any kind of validation or security checks correctly.
1.It is validated at UI level because to reduce the one extra hit to server. (EnableClientSideValidation check). And its for basic validations only(like invalid input etc)
2.Many business validations are written in Business layer where they intact irrespective to the UI(WPF or MVC)
3.Usually we write UI validation in controller and specific to MVC.
4.You should keep the validation part as per the prefrences. like sometime we validate entity for unique constraint in such case I would prefer to write my validation attribute over the Entity itself.So at the time of insertion to the database it will be validated.
Also you can try to introduce another layer(new library) here for simplicity and decoupling approach,
This new layer will do, some validation which are not specific to UI and not specific to business logic. We will call it as App Services Layer which also actually helps you to interact with WCF like scenarios. So now your controller and WCF will interact with same layer and with same validation.
Data Validation should happen at the domain level. But UI validation errors should be caught without having to ask someone else downstream.
I am developing my first DDD application and trying to follow some basic rules I've studied in these last few months.
I've implemented the repository pattern with Nhibernate.
I thought I could have "moved" my entities from the controller to the view, but soon I've realized it's almost impossible.
Most people seem to prefer to define a viewmodel specific for each view.
I don't particularly fancy the idea to redefine the fields I've already create for my entities but it seems that this is the only way.
Now I am facing the situation where I want to attach some validation rules.
I thought I could have attached the validation rules (with DataAnnotations) to the entities but it can't work if I am using a viewmodel.
Here are the questions:
Shouldn't the validation be part of the domain model?
Isn't it time consuming to create the model and then spend time to remap the same fields (properties) on the viewmodel?
Isn't this an anemic model, if it doesn't have, at least, validation rules?
I am starting to wonder if DDD is really suitable for small/medium size application.
I appreciate any help/suggestion.
This has been asked hundreds of times here and I have answered it hundreds of times (so this makes you the hundredth and first person to ask this :-)): put user validation logic on your view models (things like required fields, datetime formats, ...) and put business validation logic on your entities (things like the username has already been taken, the user can no longer purchase products on your site because he has reached the maximum quota, ...).
Shouldn't the validation be part of
the domain model?
I think it should be on both the domain model and the viewmodels. The validation on the viewmodels will check for valid input as to type --datetime, decimal,int, etc whereas the validation on the domain model should check for rules specific to the application. In this way even if you decide to use another UI the business validation will still be in place, while the UI will need to take care of the input validation.
Isn't it time consuming to create the
model and then spend time to remap the
same fields (properties) on the
viewmodel?
There are tools that can help you with that, for example, automapper on codeplex. In my opinion this results in cleaner separation between BLL and UI.
Whereas this approach is in overall more time consuming, it is also more scalable. If your application will need to grow in the future than this is a reasonable way to design the architecture.
First, before anyone screams dupe, I had a hard time summarizing it in a simple title. Another title might have been "What is the difference between a domain model and MVC model?" or "What is a model?"
Conceptually, I understand a Model to be the data used by the views and controller. Beyond that, there seems to be a great deal of differing opinions on what makes up the model. What's a domain model, versus an app model, vs a view model, vs a service model, etc..
For example, in a recent question I asked about the repository pattern, I was told point blank that the repository is part of the model. However, I have read other opinions that the model should be seperated from the persistence model and the business logic layer. After all, isn't the Repository pattern supposed to decouple the concrete persistence method from the model? Other people say there is a difference between the Domain model and the MVC model.
Let's take a simple example. The AccountController that is included with the MVC default project. I've read several opinions that the Account code included is of poor design, violates SRP, etc.. etc.. If one were to design a "proper" Membership model for an MVC application, what would that be?
How would you seperate the ASP.NET services (Membership provider, role provider, etc..) from the model? Or would you at all?
The way I see it, the model should be "pure", perhaps with validation logic.. but should be seperate from business rules (other than validation). For example, let's say you have a business rule that says someone must be emailed when a new account is created. That doesn't really belong in the model in my view. So where does it belong?
Anyone care to shed any light on this issue?
The way I have done it - and I'm not saying it is right or wrong, is to have my View and then a model that applies to my view. This model only has what is relevant to my view - including data annotations and validation rules. The controller only houses logic for building the model. I have a service layer which houses all business logic. My controllers call my service layer. Beyond that is my repository layer.
My domain objects are housed separately (in their own project, actually). They have their own data annotations and validation rules. My repository validates the objects in my domain before saving them into the database. Because every object in my domain inherits from a base class which has validation built in, my repository is generic and validates everything (and requires it inherits from the base class).
You might think that having two sets of models is duplication of code, and it is to an extent. But, there are perfectly reasonable instances where the domain object is not appropriate for the view.
Case in point is when working with credit cards - I have to require a cvv when processing a payment, but I cannot store the cvv (it is a $50,000 fine to do so). But, I also want you to be able to edit your credit card - change of address, name, or expiration date. But you aren't going to give me the number or the cvv when editing it, and I certainly am not going to put your credit card number in plain text on the page. My domain has these values required for saving a new credit card because you give them to me, but my edit model doesn't even include the card number or cvv.
Another benefit to so many layers is that if architected correctly, you can use structuremap or another IoC container and swap out pieces without detrimentally affecting your application.
In my opinion, controller code should only be code targeted at the view. Show this, hide that, etc. The service layer should house the business logic for your app. I like having all of it in one place so it's easy to change or tweak a business rule. The repository layer should be relatively dumb - devoid of business logic and only query your data and return your domain objects. By separating the view models from the domain model, you have much more flexibility when it comes to custom validation rules. It also means you don't have to dump every piece of data into your view in hidden fields and push it back and forth between the client and server (or rebuild it on the backend). Your view model will then house only the information relevant to the view - and it can be customized to have bools for view logic or counts or enums so that the view itself isn't cluttered up with complicated logic statements like
<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) &&
Model.SomeObject.SomeInt == 3 && ...) { %>
While everything seems spread out and over-layered, it has a purpose for being architected this way. Is it perfect? not really. But I do prefer it to some past designs of calling repositories from the controller and having business logic mixed in the controller, repository, and model.
I too often wondered how exactly the MVC elements fit in a traditional web application structure, where you have views (pages), controllers, services, and data objects (model). As you said, there are many versions of that.
I believe the confusion exists because of the above stated, widely accepted architecture, which uses the "anemic domain model" (alleged)-anti pattern. I won't go into much details about the "anti-patternness" of anemic data model (you can look at an effort of mine to explain things here (Java-based, but relevant for any language)). But in short, it means that our model holds only data, and business logic is placed in services/managers.
But let's assume we have domain driven architecture, and our domain objects are the way they are expected to be - having both state and business logic. And in this domain-driven perspective things come into place:
the view is the UI
the controller gathers the inputs of the UI, invokes methods on the model, and sends back a response to the UI
the model is our business components - holding the data, but also having business logic.
I guess that answers your main questions. Things get complicated when we add some more layers, like the repository layer. It is often suggested that it should be invoked by the business logic placed in the model (and hence each domain object has a reference to a repository). In the article of mine that I linked I argue that this is not quite a best practice. And that in fact it is not a bad thing to have a service layer. By the way, domain-driven design does not exclude the service layer, but it is supposed to be 'thin', and only coordinating domain objects (so no business logic there).
For the anemic data model paradigm, which is widely adopted (for good or for bad), the model would be both the service layer and your data objects.
In my opinion,
Model -
Should not contain business logic, it should be pluggable(WCF like scenario). It is used to bind to view so, it should have properties.
Business Logic -
It should be placed at "Domain Services Layer", it is separate layer altogether.
Also, will add one more layer here "Application Services".
App Services talks to Domain Services layer to apply business logic and then lastly return the Model.
So,
Controller will ask Application Service for Model and the flow will go like,
Controller->Application Services(using domain services)->Model
The MVC pattern and the Asp.net framework makes no distinction on what the Model should be.
MS's own examples include persistence classes in the model. Your question about membership being in the model. This depends. Are classes in your model owned by something? Is there a link between who logs in and what data is displayed? Is there filtering of data part of a permissions system that is editable? Is who last updated or edited an object part of your domain as in somebody else needs to see it or something for backend support?
The email example is also it depends. Are you familiar with domain eventing or eventing in particular? Do you have a separate service to send emails? Is the act of sending an email part of your domain or is it a application level concern outside of the scope of your system? Does the UI need to know if an email was sent successfully or not? Do emails that fail to send need retries? Does the content of the email sent need to be stored for support or customer service requirements?
These types of questions are overly broad and subjective but I'm answering so you and everybody who voted you up can understand this.
Your requirements/timelines/resources all bleed into your system's architecture. Even the revenue model can have an effect. You also have to consider the pattern you are shooting for. DDD is much different than persistence-as-model applications and all the slop in between are also valid for certain apps. Are you shooting for testing the app? All of this has an effect.