We do like EntityFramework (CTP5) quite a lot and Using it along with ASP.NET MVC3.
What I dislike is;
things are mixed in together.
I can place a DisplayAttribute, RequiredAttribute, RangeAttribute, CompareAttribute together in the same class which means I am mixin in database validation, some business logic and UI alltogether. I can even place ScriptIgnore attribute to customize it as a Json DTO object. So I can use the same POCO class for Persistance, Presentation, DTO and Business Object, and as my domian model.
Which design patterns do you follow along with EF POCO + MVC3 toolset. What layers do you have?
What resposibilities do you add to your classes (Is Your POCO class also your Domain Model)
I use View Models to solve this problem. Validation and UI presentation attributes go to the view model. In this pattern the controller uses a repository to fetch an EF model, maps this EF model to a view model (I use AutoMapper for this) and passes the view model to the view. Because the view model contains all the UI presentation attributes the view behaves as expected. Each view must have its own view model. This means that you could have multiple view models associated to the same EF model but contain a different subset of properties and display formatting attributes based on the specific requirements of the view.
The process works the other way around as well: the controller receives a view model from the view as argument. It maps the view model back to a model and passes the EF model to the repository. UI validation attributes are handled on the view model because you could have different validation requirements in different views: think for example Insert/Update views. In the insert view you will be creating a new entity thus the Id property won't be required. You won't even have an Id property on your view model in this case. In the update view on the contrary the Id property will be required.
My POCO classes are almost always domain models and almost never view models so I don't have these problems.
The best practice is to use special "view model" class when passing data from controller to view (or as JsonResult). In such case you mark UI based attributes in that view model. In most cases (except pure crud applications) you need to display something more or something less then your domain object so you still need some view model (unless you use ViewData directly).
Data annotations on domain object makes sense only if you want to use them for business/data level validation which can take different rules then UI validation.
If you want to follow strict DDD where POCO classes are domain objects = offers methods performing domain logic on instance of object you should go even further because in such case your business facede should not expose domain objects to controller. In such case you will end up with data transfer objects exposed on business facade and consumed in controller. I'm not purist so in this scenario I'm open minded to using data annotations on DTOs directly but it depends on another requirements.
Related
I'm currently working with EF4 and asp.net mvc 3 and I'm certainly having some trouble working through the different types of models that are possible when you bring these technologies together.
I have a database that I've defined and through EF4 I have a model of my database. But there is also the model that gets passed to my view and what about view models???
Lets say I have a mvc model of a project. This project has description, name and category properties. I have a view page that creates a project and returns it back to the controller for insertion into the database through ef4. So I initially created a class with those exact properties to be my model. However my page also requires a list of categories to choose from when creating that project, so I added a string array to my model which got passed to the page along with the other properties as part of my project model and it worked fine. Everything is great ... but I got to thinking ... because if the project model models a project then it shouldn't have a complete list of categories. It should only have the category that is part of that project.
But where does this complete list of categories go. In the view bag? This seems incorrect to me? Should I be creating a view model? How would this view model look? How about adding a method to the project model that would be something along the lines of GetCategories() then I could call this method from the view page ... but does that break the separation of concerns ideal in mvc?
I'm sure many people will have different views on the subject but any commentary that will help me wade through this mess will help.
Thanks,
In all the but simplest applications you're best off not passing Model objects to Views. A View should have a ViewModel which is constructed by a Controller using data from Model objects and which contains everything that View needs to display its information.
ViewModels decouple your presentation layer from your business layer, and your example demonstrates why this is important; your View needs information about a Project, but also a complete list of all Categories that Project could belong to - such a list does not logically fit into the Project domain model object, but fits perfectly logically into a ProjectViewModel.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
ASP.NET MVC - Linq to Entities model as the ViewModel - is this good practice?
Is is OK to use EF entities classes as view models in ASP.NET MVC?
What if viewmodel is 90% the same of EF entity class?
Let's say I have a Survey class in Entity Framework model. It 90% matches data required for view to edit it.
The only difference from what view model should have - is one or several properties to be used in it (that are required to populate Survey object because EF class cannot be directly mapped onto how it's properties are represented (sub-checkboxes, radio groups, etc.))
Do you pass them using ViewData[]? Or create a copy of Survey class (SurveyViewModel) with new additional properties (it should be able to copy data from Survey and back to it)?
Edit:
I'm also trying to avoid using Survey as SurveyViewModel property. It will look strange when some Survey properties are updated using UpdateModel or with default binder, while others (that cannot be directly mapped to entity) - using SurveViewModel custom properties in controller.
I like using Jimmy Bogard's approach of always having a 1:1 relationship between a view and a view model. In other words, I would not use my domain models (in this case your EF entities) as view models. If you feel like you are doing a lot of work mapping between the two, you could use something like AutoMapper to do the work for you.
Some people don't like passing these model classes all the way through to the view, especially as they are classes that are tied to the particular ORM you're currently using. This does mean that you're tightly binding your data framework to your view types.
However, I have done this in several simple MVC apps, using the EF entity type as the Model for some strongly-typed views - it works fine and is very simple. Sometimes simple wins, otherwise you may find yourself putting a lot of effort and code into copying values between near-identical Model types in an app where realistically you'll never move away from EF.
You should always have view models even if they are 1:1. There are practical reasons rather than database layer coupling which I'll focus on.
The problem with domain, entity framework, nhibernate or linq 2 sql models as your view classes is you cannot handle contextual validation well. For example given a user class:
When a person signs up on your site they get a User screen, you then:
Validate Name
Validate Email
Validate Password Exists
When an admin edits a user's name they get a User screen, you then:
Validate Name
Validate Email
Now expose contextual validation via FluentValidation, DataAnnotations Attributes, or even custom IsValid() methods on business classes and validate just Name and Email changes. You can't. You need to represent different contexts as different view models because validation on those models changes depending on the screen representation.
Previously in MVC 1 you could get around this by simple not posting fields you didn't want validated. In MVC 2 this has changed and now every part of a model gets validated, posted or not.
Robert Harvey pointed out another good point. How does your user Entity Framework display a screen and validate double password matching?
On bigger projects, I usually split up business objects from data objects as a matter of style. It's a much easier way to let the program and database both change and only affect the control (or VM) layer.
The DataAnnotations validation happens in the default model binder and most of the examples I've seen uses the Model.IsValid in the Controller to verify if a model is valid or not. Since my controller action calls a business layer method and I like to validate the entity there:
Do I have to explicitly switch off
the model binder validation?
How do I validate the entity in the
business layer. In other words, how
do I trigger validation given an
object?
Also, I am using View Models. Do I
add the validation attributes to the
view model? If so, since View models
are being tied to the UI, what about
validation at the business layer??
I'm gonna start by answering your question #3: yes, when using view models, add Data Annotation validation attributes right on the properties on your view model. As you pointed out, the view models are tied to the UI so they have presentation concerns and the validation is strictly for UI input validation. The validation attributes you apply here will be automatically invoked by the framework and you can check ModelState.IsValid in your controller (which you also pointed out).
In reference to validating objects in your business layer, there are numerous ways to do this. For example you could also use data annotations on your business layer domain model entities as well. You could also use other frameworks like Enterprise Library validation application block, Fluent Validation, etc. But in this case, you're probably going to be making an explicit call to validate your domain objects (and each of these frameworks has their own mechanism for doing so). I'm presuming your mapping between your view models and domain models (probably with something like AutoMapper) given your description above.
Having said all that, in reference to your question #1, I would not switch off model binder validation. Let that performance the validation on your view models as normal. Map your view models to your domain model classes. Then feel free to perform an additional layer of business object validation for your domain model. You may not even doing this validation in the MVC project - this might be encapsulated in a business layer that you have somewhere else in your app.
Is it reasonable to mix view models with domain models?
So i.e. the view model object contains some domain model objects (not the other way around!)
Generally, you will have to reference your Domain Models in your View Models, or at least load the Domain Models in the controllers and pass the information on to your View Model.
I prefer to keep Controllers and Views as simple/dumb as possible, because both Domain Models and View Models are FAR easier to test.
So, I often reference my Domain Models inside my View Models. Sometimes I use aggregation, sometimes I just copy over properties (In some projects just with plain old code, in other projects using an auto mapper)
I tend to create separate view models that contain just what I need to be displayed in the view. AutoMapper is a create tool for making this easier.
I'm using NHibernate to persist my domain objects.
To keep things simple I'm using an ASP.NET MVC project as both my presentation layer, and my service layer.
I want to return my domain objects in XML from my controller classes. After reading some posts here on Stack Overflow I gather DTOs are the way to go. However, I've also come across posts talking about the ViewModel.
My question: Are Data Transfer Objects and ViewModels the same thing? Or is a ViewModel a kind of sub pattern of a DTO?
The canonical definition of a DTO is the data shape of an object without any behavior.
ViewModels are the model of the view. ViewModels typically are full or partial data from one or more objects (or DTOs) plus any additional members specific to the view's behavior (methods that can be executed by the view, properties to indicate how toggle view elements etc...). You can look at the viewmodel as all the data for a view plus behaviors. ViewModels may or may not map one to one to business objects or DTOs.
By the way, NHibernate projections come in handy if a certain viewmodel needs a subset of the data from a persisted object.
ViewModel in ASP.NET MVC practice is the same as the DTO, however ViewModel in MVVM pattern is different from DTO because ViewModel in MVVM has behaviors but DTO does not have.
DTO != ViewModel
In the MVVM pattern the ViewModel is used to isolate the Model from the View. To represent the Model you could use simple DTO classes, which again is mapped to a database through e.g. NHibernate. But I've never seen a ViewModel class which is modelled as a DTO.. ViewModel classes mostly have behavior, which DTOs don't have.
DTO - Data Transfer Objects are exactly as it says, containers for transferring data. They have no behaviour but merely a bunch of setters and getters. Some people make them immutable and just create new ones when needed rather than updating existing ones. They should be serializable to allow transfer across the wire.
Generally DTOs are used to ship data from one layer to another layer across process boundries as calls to a remote service can be expensive so all the required data is pushed into a DTO and transferred to the client in one chunk (coarse grained).
However, some people use the notion of screen bound DTOs (nothing to do with crossing process boundries). Again these are populated with the required data (generally the data required for a particular screen and could be an aggregation of data from various sources) and sent to the client.
http://blog.jpboodhoo.com/CommentView,guid,21fe23e7-e42c-48d8-8871-86e65bcc9a50.aspx
In simple cases as has already been stated this DTO can be used for binding to the view but in more complex cases it would require the creation of a ViewModel and unloading of data from DTO to ViewModel which is obviously more work (when applying MVVM pattern).
So again as already stated DTO!=ViewModel
and
DTO and ViewModel have different purposes in life
For some simple views I'll use my DTO as my models, but as Views become more complex I'll create ViewModels.
For me it is a balance between quickness (using DTO, since I already have 'em) and flexibility (creating ViewModels means more separation of concerns).
First, the major difference is that ViewModel can have behaviour or methods that DTO Must Not !!!
Second, Using DTO as a ViewModel in ASP.NET MVC make your application tightly coupled to DTO and that's exactly the opposite purpose of using DTO. If you do so, what's the difference using your domain Model or DTO, more complexity to get an anti-pattern ?
Also ViewModel in ASP.NET can use DataAnnotations for validation.
The same DTO can have different ViewModels Mapping, and One ViewModel can be composed from differents DTO (always with object mapping not composition) . because i think it is even worse if you have a ViewModel that contains a DTO, we will have the same problem.
From your presentation layer, think about DTO as a contract, you will receive an object that you have to consider as stranger to your application and don't have any control on it (even if you have ex the service, the dto and presentation layers are yours).
Finally if you do this clean separation, developpers can work together with ease.
The person who design ViewModels, Views and Controllers don't have to worry about the service layer or the DTO implementation because he will make the mapping when the others developpers finish their implementation...
He can even use Mocking tool or manual mocking to fill the presentation layer with data for test.
If you need to change or enhance the DTO then create a ViewModel. It's also OK for the ViewModel to reference the DTO as a complex property.
In practice, you will generally want to add view-specific properties or methods to the model you are using in the view. In such cases,
never modify the DTO for your view requirements. Instead, create a ViewModel and map from your DTO to the ViewModel.
If you will use DTO as ViewModel, that means you are making high dependency on DTO because of some reason you are changing DTO then it could impact on ViewModel.
Better use DTO & convert into viewmodel.
We can use DTO same as Model class and we can use viewmodel when we needs to show/use multiple models data/property in a single view. Example: I create some model using entity framework database first. So, now all the model generate based on the database. and now we need data annotation, for those data annotation we can create a folder name DTO, In this DTO folder, we can keep all the models exact which already generate and add data annotation above the property. Then we can use any operation(use controller , views) using this DTO classes. And when we need complex view, I mean when we need multiple classes data in one view there we can use viewmodel. For viewmodel we can create a folder name viewmodel, then create a custom class and keep that property which we need. I tried to clear myself. Any suggestion highly appreciated.