EF4 models and MVC models and view models ... To model or not model? - asp.net-mvc

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.

Related

difference between models and view models

I have been researching asp.net MVC project structure's for a new project and have a question about something is confusing me. What is the difference between models and view models? Would I be correct in saying that view models encompass models in the form properties?
I've a blog where I want to display the list of the latest posts, latest comments, post categories in a single view. How I can do that? I can strongly type my view to any one of the model right? There comes view model.
I created a view model called BlogViewModel that contains latest posts, latest comments and other stuff as properties and I bind my view with this model. The posts, comments.. are domain models while the BlogViewModel is the view model I created specially for the view.
Tomorrow I'll show my blog in a mobile version and at that time I may create a simple view model that contains only less properties. Finally.. view models are for views and most of the times they acts as wrappers over the real domain models!
A model is usually more closely related to how your data is stored (database, services, etc.) and the model will closely resemble those.
The ViewModel on the other hand is closely related to how your data is presented to the user. It is usually a flatten version of your model, denormalized, etc. It can be the aggregation of multiple models.
For your typical Person objects, your model may contain properties like the following:
FirstName
LastName
BirthDate
However, in your ViewModel you may choose to represent it differently and have something more like:
FullName
Age
ViewModel is the version of a Model from the business-domain layers adjusted to the specific View.
It has only Properties relevant to the view and shouldn't have methods(except simple ones like ToString()).
ViewModel is a "data container" only.
A model is simply a representation of an object in your application. However, there are a few different types of models that you should be aware of.
Domain Model: This represents a domain object in your application, like a SQL table if you are using an ORM (Linq2SQL, EF).
View Model: This represents an object that you want your end users to view/edit/etc. A view model could contain properties from several or no domain models and typically exclude properties that your end users should not be mucking with. View Models should only contain the elements that are needed to display the appropriate data to the end user for a specific request.
Here is some Jimmy Bogard for you about View Models and their use.

Scope of viewmodels in asp.net MVC 3

I have read online that it is bad practice to use a "kitchen sink" model:
Rule #3 – The View dictates the design of the ViewModel. Only what is
required to render a View is passed in with the ViewModel.
If a Customer object has fifty properties, but one component only
shows their name, then we create a custom ViewModel type with only
those two properties.
Jimmy Bogard's subsequent explanation of how this is good, however, left me a little questioning. It'd be so easy to have my Model just contain a list of Customers, I could even use my POCO's.
So now I get to create custom little view model fragments for every page on the site? Every page that uses a Customer property would get one, but of course could not be shared since some of the information is extraneous, if one page used Age but not Name, for example. Two new mini view model classes right?
This is very time consuming, and seems like it'll lead to a million little custom view models - can someone elaborate as to the utility of this approach and why the easier approach is bad?
View model class can be used not only to transfer values, but it also defines data types (data annotations), validation rules and relations different then ones used in model. Some advantages that come to my mind right now:
There are different validation rules when you change user's password,
change his basic data or his subscription setting. It can be
complicated to define all these rules in one model class. It looks
much better and cleaner when different view models are used.
Using view model can also give you performance advantages. If you
want to display user list, you can define view model with id and name
only and use index to retrieve it from database. If you retrieved
whole objects and pass it to view, you transfer more data from
database than you need to.
You can define display, and editor templates for view models and reuse them on different pages using html helpers. It looks much worse, when you define templates for model POCOs.
If you would use your POCO objects as view models, you would essentially be showing your private objects and break the encapsulation. This in turn would make your model hard to change without altering the corresponding views.
Your data objects may contain details that are appropriate only to the data access layer. If you expose those things to the view, someone might alter those values that you did not expect to be altered and cause bugs.
Many of the same reasons as for having private members in OO languages apply to this reasoning. That being said, it's still very often broken because it's a lot of extra work to create all these "throw-away" models that only gets used once. There exists frameworks for creating these sorts of models, though the name eludes me, that can tie objects together and pick out the interesting properties only which takes away some of the drudgery from creating specific view models.
Your View Model tells the View how data should be shown. It expresses the model. I don't think its necessary to have two view models unless you have two ways to express your model. Just because you have two pages, doesn't mean you will be showing the data any different way, so I wouldn't waste time making two mini View Models when it can be in one reusable view model, Imagine if later you have a page that needs Name and Age, you would create another view model? It's absolutely silly. However, if you had two pages both showing 'Age' and it needed to be shown in a different way, then I would create another one.

entity framework POCO + recommended patterns

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.

ASP.NET MVC: using EF entities as viewmodels? [duplicate]

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.

Bestpractice - Mixing View Model with Domain Model

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.

Resources