Benefits of not passing entities to view - asp.net-mvc

I usually see people telling that you should not pass entities to your View. They say you should use a DTO/VO/ViewModel/AnyOtherThingYouWant instead, as using an entity would increase the coupling.
Ignoring the moments where I do need some extra logic (or I don't need all the properties), I fail to see any benefits in doing this. For example, consider the following class:
public class Contact {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
I see lots of code that creates another class, like this:
public class ContactDTO {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
use it in the View and then do this:
someMapper.Map(contactDto).To<Contact>();
I can't see how better this is than simply using the Contact class, as your View would be coupled to a class that is coupled to the entity's class. So, every change in one should be replicated into the other. From my point of view, the 'middle' object is there just to add complexity, but not real value.
I know that there's no 'one size fits all' solution (as sometimes, using the middle object would make sense), but do we really need adding code like this? What are the real benefits?

Think of it this way: a view is a projection of your domain. It's a specific representation of your business model. So you need to use a view model which will represent this projection. It could be a subset of the domain model but it could also be an aggregation of multiple domain models if the view requires it. The example you provided is just a specific case where there is a 1:1 mapping between the domain model and the view model because of the requirements of this specific view. But that's only one specific view. I suppose that your application has many views and different representations of your domain entities.
There are many view specific things that make your domain models unsuitable and thus the need of view models. For example validation. A given domain model property could be required in some view and not required on another view (think of Id property in Create/Update views). If you don't use a view model but have your Create controller action directly take the domain model you will have a problem if your domain model Id property is decorated with the Required attribute.
There are many other examples. If I had one advice to give you when developing an ASP.NET MVC application it would be this: always define specific view models for your views and never pass/take domain models to/from views and this stands true even in cases where you have a 1:1 mapping between your domain model and the view model.

The cited approach is a kind of purism. If you do not need to transform (reduce, merge, whatever) your domain objects and they are directly usable in your view as they are, use them - you can introduce DTO via refactoring later, when necessary.
So you have to take into consideration what Darin Dimitrov said but keep in mind that DTOs and similar are here to make your work easier. I recall one project I worked on - more than 90% of DTOs were ono-to-one copies of the domain objects - this is totally useless and only adds to the maintenance cost.

Related

Using an MVC Model as a filter in the repository

I have a details view that is typed to IEnumerable. The view with a bunch of drop downs that let you add filters to the list of records rendered.
All these dropdowns correspond to properties on the MVC model:
public class Record
{
public string CustomerNumber { get; set; }
public string CustomerName { get; set; }
public string LineOfBusiness{ get; set; }
public DateTime? Date { get; set; }
}
Now, I'm using my model as my dto to shuffle data between my controller and my repo. Since all my drop down filters represent the model properties, I pass my model to a repo retrieval method, check its properties and filter based on its values? In other words:
public IEnumerable<TradeSpendRecord> Get(TradeSpendRecord record)
{
IQueryable<tblTradeSpend> query = _context.tblRecords;
if (!String.IsNullOrEmpty(record.CustomerName))
query = query.Where(x => x.CustomerNumber == record.CustomerNumber);
if (!String.IsNullOrEmpty(record.LineOfBusiness))
query = query.Where(r => r.LOB == record.LineOfBusiness);
SNIP
Hope this isn't too subjective, but I'm wondering if anyone has any input about whether this is a good/bad practice. I haven't seen a whole lot of examples of dynamic filtering like I need to do, and am looking for some guidance.
Thanks,
Chris
If you're doing what I think you're doing, I'm not sure this is the best way of doing it.
Keep your 'Models' in your MVC/presentation layer (whether this is one physical assembly or not) dedicated to your presentation layer. The only things that should be touching them are your Views and your Controllers. You don't want what should be independent entities to be so tightly coupled to your View Models.
I'd suggest creating a separate TradeSpendFilter class, which, at its simplest, exposes the filterable properties of your domain entity (likely more than any given View Model). You'd then pass this into your "filtering service" or whatever it may be. This also means you can extend your filtering functionality independent of both your domain models and your MVC app. For example, if you suddenly want to filter multiple objects, you can simply change...
public class TradeSpendFilter
{
public string CustomerName { get; set; }
...
}
...to...
public class TradeSpendFilter
{
public IEnumerable<string> CustomerNames { get; set; }
...
}
... without causing all sorts of problems for your MVC app.
Additionally, it will also mean you can make use of your filtering functionality elsewhere, without tying further components to your MVC app and ending up in a bootstrapped mess.

ASP.NET MVC Done Right: View Models

I read this q/a Real example of TryUpdateModel, ASP .NET MVC 3 and was really interested on #ben-foster response.
I started doing a comment on that answer but got quite long, so started a new Question.
Having ViewModels for everything approach (which i like a lot) get me into some 'weird scenarios' that i want advice in how should I do.
Imagine this structure :
public class ProductListEditableViewModel {
List<ProductEditViewModel> products {get;set;}
}
public class ProductEditViewModel {
List<PriceViewModel> prices {get;set;}
}
public class PriceViewModel {
CurrencyViewModel currency {get;set;}
}
and so on ... ? do you really make one view model for each inner class? how then you map all that to the Model Object?
Also, that covers the Edit, but I have an Add, a send via email, and potentially more Views so more ViewModels!! should i end like something :
AddCurrencyViewModel
QuickAddCurrencyViewModel
EditCurrencyViewModel
ListCurrencyViewModel
DeleteCurrencyViewModel
ShareCurrencyViewModel
all having the 'almost same' properties ?
Should all those be packed into one file ?
Also do i need all this all viewModels or a inheritance approach might be better?
If you can, I´ll appreciate elaborate on complex scenarios
Also, I use a DTO approach to expose some of the model objects into web service / apis, so I already have some form of mapping already in place where this DTO are not exactly my ViewModels, should I remove one of them? what´s the suggestion in this scenario ?
I´m using entity framework but i think the question is (or should be) ORM agnostic.
Not using UoW pattern (will this helps?) as looks it´s gets more complicated as the depth of the object increases.
Thanks a lot!
We typically have a view model per view so yes, if you have lots of views you will have lots of view models.
In typical CRUD applications we often have very similar views, for example Add and Update. In these cases, yes we use inheritance rather than writing duplicate code - usually Add subclasses Update.
public class AddFoo : UpdateFoo {
public AddFoo() {
// set up defaults for new Foo
}
}
public class UpdateFoo {
public string Name { get; set; }
// etc.
}
We attempted to "share" view models between views in the past and normally ended up in a world of pain.
With regard to your "weird scenario" - this does look weird indeed, but perhaps because I don't understand your application.
The goal of your view model is to provide the information to the view that is needed and ideally to flatten any complex objects so they are easier to work with. You shouldn't split your view models up like your example unless it makes sense to do so.
Let's say I wanted to a create a view where the customer could change their contact details. Taking the following domain object:
public class Customer {
public string FirstName { get; set; }
public string LastName { get;set; }
public Address Address { get; set; }
}
I'd probably flatten this to a view model like so:
public class UpdateAddressModel {
public string FirstName { get; set; }
public string LastName { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressCity { get; set; }
// etc.
}
Of course there will be occasions where it doesn't make sense to do this, for example a dashboard view in an online store where you have a list of products going out of stock and a list of recent orders - these two things are unrelated but are required by your view:
public class DashboardModel {
public List<Product> ProductsGoingOutOfStock { get; set; }
public List<Order> NewOrders { get; set; }
}
how then you map all that to the Model Object?
I'm assuming by Model Object you mean your data/domain model. The key takeaway here is that the view model you use to render your view is unlikely to be the same as the "models" you POST to the server and if they are, you're probably over-POSTing or you have some crazy enter-everything data capture screen that will make your eyes bleed.
I find it helps to think of what you send to your server as Commands and what you use to render your views as view models.
So the answer to your question - how do you map your complex view model to your data model? - Quite simply, you don't. You should send commands to the server that perform a specific task e.g. updating an address.
There's no hard and fast rule in how you structure your view models but generally go with what makes sense and if it starts to feel too complicated you're probably trying to do too much with one view.
I hope this helps. You'll find lots of posts relating to this matter on my blog.
I realize this is an old-ish question but I did want to address one of the questions posed by the OP that was not answered.
Should all those [ViewModels] be packed into one file ?
Most of the examples I see put each ViewModel in a separate file, so the dominant convention seems to be one file per viewmodel, but I found in practice that this seems to be overkill. Instead I put all viewmodels for a particular controller in one file with multiple viewmodels in it. So for example if User is my Controller and I have several viewmodels associated with this controller such as UserAddViewModel, UserEditViewModel, UserDeleteViewModel I put all of the viewmodels for User in one file called UserViewModels.cs

Why does the interaction between model, view and contoller look different?

Im new to ASP.NET MVC, trying to learn the basics.
Im now trying to learn the relationship between the model ,view and controller.
The interaction between these three looks different, why? (Look at the arrows)
Source 1: MSDN
Source 2 (Page 65): Steven Sanderson
I would be glad if you help me sort out my confusion
Thanks
Edit:
What you are saying is that mvc can be implemented differently?
(Still asking about asp.net mvc - Not mvc in general)
I have been looking at the mvcmusicstore
and it looks like this.
Controller:
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
Model:
public class Album
{
public int AlbumId { get; set; }
public int GenreId { get; set; }
public int ArtistId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public Genre Genre { get; set; }
public Artist Artist { get; set; }
}
view:
(Had to add as image, add code the normal way did not work)
This looks like the MSDN version, how would this be rewritten to fit Sandersons diagram?
Maybe this will help me understand!
Edit again:
Hi again
Let me sum this up. Please respond if I'm wrong.
The way Microsoft intended us to use mvc is the one we see in the above MSDN link and in MusicStore.
Then there are other "versions" of mvc such as Sandersons (or whereever it originates from).
So Microsoft give us a basic way of how to use the mvc framework, but it is ok to do it other ways.
A newbie should not get stressed by seeing different versions, sticking to the one seen in MSDN/MusicStore is perfectly fine.
The key difference is the inclusion of the "Presentation Model" in Sanderson's diagram. The ASP.NET MVC implementation often uses the Model as the Presentation Model, even though they can be different (and I would argue that they should be different, but it's a holy war and there's no need to get into that).
In most very simple ASP.NET MVC applications, the model is the data entity. Whether it's an EF entity or a Linq2Sql entity, makes no difference. This is because most applications are simple forms-over-data and the presentation is probably one-to-one with the persistence.
The MVC pattern itself, however, doesn't require this. In a more pure framework-agnostic form, Sanderson's diagram illustrates the fact that the controller is interacting with the model. The model is really the "gateway to the domain core" in this sense. Controllers and views are part of the application, but the model has the underlying business logic and, beneath that, layers of persistence and other infrastructure information (properly separated, of course) which are unknown to the application. The boundary between the controller and the model is the application boundary, the point at which other applications can also connect to the domain core and interact with it.
A presentation model is usually nothing more than a simple value object. It's not an entity of any kind in the sense that it doesn't have to exhibit any business behavior or maintain its lifecycle the way that a persistable business entity would. It's just a flat object with some attributes of data.
It can have some behavior, but that behavior is for the application and not for the domain core. For example, maybe it has some methods or properties that the view can use. The presentation model is part of the application, so it's presentation-layer-aware. Essentially it just holds data that the controller needs to pass to the view (or even receive from the request, depending on the framework).
In ASP.NET MVC you'll very often see the model used also as the presentation model. The same object may be playing two roles in those cases, but the two roles are definitely different.
Edit: Just noticed your updated question...
In that example, Album is playing the role of both domain model and presentation model. (In fact, I would argue that it's not a domain model at all because it's too anemic. Notice that it has no functionality, just bare data.) In a richer domain model, Album would likely have more functionality. For a contrived example, imagine that instead of auto-implemented properties it has properties which enforce business logic when set, and it has methods on it such as AddSong(Song song) and Play() and other such behaviors.
This richer model can still be used as a presentation model, but the functionality might not make sense in the scope of a view. A view is really suited more toward just bare data elements. The controller would interact with the model's functionality. So you might create a presentation model similar to the Album domain model in structure, and it would look just like the one in your example.
Going forward, what if the view needs other data as well? Maybe the view needs to know something about other models which aren't part of the same aggregate as Album. It wouldn't make sense to modify the domain models to accommodate the view. That's backwards. The presentation should wrap around the domain core, not the other way around. So you might add properties to the presentation model which are populated from other things inside the controller.
So you might end up with something like this...
Domain model:
public class Album
{
public int ID { get; private set; } // might need to be immutable
private string _title;
public string Title
{
get { return _title; }
set
{
// don't allow empty titles
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentNullException("Title");
_title = value;
}
}
private Album() { }
public Album(int id, string title)
{
ID = id;
Title = title;
}
public void Play()
{
// some implementation
}
public void SomeOtherMethod()
{
// some implementation
}
}
As the business domain grows and changes, this model could change with it. The main point is that it changes at the behest of the domain core and the business logic, not at the behest of UI implementations.
A particular "page" on a particular website which uses this domain core may need specific information about an album, and maybe some other information as well. You'd tailor a presentation model to fit that:
public class AlbumViewModel
{
public int ID { get; set; }
public string Title { get; set; }
public string Owner { get; set; }
public IEnumerable<Listener> Listeners { get; set; }
public string SomeCompletelyUnrelatedValueNeededByTheView { get; set; }
}
The controller would then construct this presentation model for the view:
public ActionResult Details(int id)
{
// TODO: validate and sanitize any inputs
var album = AlbumRepository.Get(id); // after all, why bind the UI _directly_ to the DB? that's just silly
var someOtherObject = SomeOtherRepository.Get(someOtherValueFromSomewhereElse);
var albumVM = new AlbumViewModel
{
ID = album.ID,
Title = album.Title,
Owner = somethingElse.SomeValue,
Listeners = someOtherObject.GetListeners(album),
SomeCompletelyUnrelatedValueNeededByTheView = "foo"
};
return View(albumVM);
}
This is a much more manual approach overall. It's useful when you have more complex domain models, multiple complex applications interacting with that domain, different technology stacks throughout the domain, etc. For simple forms-over-data applications the standard ASP.NET MVC implementation usually works fine. Most of the tutorials for it reflect this, consolidating multiple responsibilities into fewer objects, using decorators instead of explicit code (assuming the use of the same stack of tools across the board), etc.
The examples you're looking at get you to a working application very quickly with very little code. As with any framework, it works beautifully if you do things the way the framework intends you to do them. If you need to step outside the bounds of the framework, you can still maintain the pattern in a more abstract and framework-agnostic way.
Edit: For your update again...
In a way, yes. ASP.NET MVC is a framework which borrows a lot from the MVC pattern in general. As with all things, there's more than one way to do it. Sticking with simple implementations and quick applications, the functionality provided by the ASP.NET MVC framework and explained in its various tutorials is perfectly acceptable and is a great example of the use of a framework... Using a tool to get a job done.
They stick to the pattern in all the most meaningful ways. At the same time, however, in the true nature of a framework (which is generally outside the scope of a pattern description), they try to give you tools which make very light work of the actual development. If you don't have a pressing need to separate your domain models from your presentation models, you don't have to. One model can play both roles. If you don't have a pressing need to abstract your data access behind, say, a repository pattern, you don't have to. You can throw together some quick Entity Framework functionality directly in your Models and be done with it.
Ultimately it's up to the needs of the project, the preferences of the developer(s), and so on. The patterns are more academic, the frameworks are more pragmatic. Balancing the two is the key.
I guess the distinction is that in asp.net MVC you can have strongly typed views which have 'knowledge' of your model and the entity being passed through to the view. In its purest sense though the View shouldn't (or rather, neednt) have any knowledge of the model. For that reason I say Steven Sandersons example is better.
Fantastic book by he way!
I wouldn't sweat it - Stephen Sanderson's diagram is showing less of the cycle but in more detail.
I'd interpret the MS article arrows as:
Controller populates model (from services, etc)
Controller directs to view
View populates through binding model
The microsoft diagram isn't really that useful or informative or useful though in my opinion. You could equally argue that arrows could go in different directions - or even in both directions like Sanderson's do. E.g. Controller also received models from binding, etc.
The Sanderson arrows are annotated well and are self-explicit, and the book is great.

Correct use of Model vs Controller in MVC / ASP.NET MVC

I have a Service class with a method called GetProducts(). That encapsulates business logic and calls the repository to get a list of products.
My MVC view wants to show that list of products as an MVC SelectList. Where is the correct place for that logic to go. I seem to have 3 options:
Model
The Model should expose a property called ProductSelectList. When the getter of this property is called by the View, the Model should call Service.GetProducts() and convert the result to a SelectList before passing it on.
Plausible argument: The Model should make calls to business logic and the repository. The View should merely render predetermined data. The Controller should not be involved, save for passing contextual data to the Model.
View
The View should contain code that calls Service.GetProducts() directly and converts the result to a SelectList inline.
Plausible argument: The View should call for this data directly as it is specifically for use on the View. There is no need to involve the Model or Controller, as we are calling an abstracted Service method anyway, so anything else just adds extra overhead.
Controller
The Controller should make the call to Service.GetProducts(), convert the results to a SelectList and pass it through to the Model, which should contain a simple ProductSelectList property. The View will access this property for rendering.
Plausible argument: The Controller knows which parameters to provide to the Service method, so it should make the call. The Model should be a simple placeholder for data, filled by the Controller. The View's job is to simply render the data from the Model.
I have a feeling that the correct answer is Model, but the other two make some reasonable points. Perhaps I've muddied the waters by already having a Service class that's separate to the Model?
Would anybody care to share their opinion? Is this just a matter of taste?
I personally subscribe to the logic of Number 3, allowing the controller to populate the Model (or View Model as is sometimes differentiated).
I have my views dumb and only displaying data.
I have my View Models store the information that the View will need, occasionally exposing 'get only' properties that format other properties into a nicer format. If my model needs access to my services, then I feel I'm doing something wrong.
The controllers arrange and gather all the information together (but do no actual work, that is left for the services.
In your example, I would have my controller action similar to:
public ActionResult Index()
{
IndexViewModel viewModel = new IndexViewModel();
viewModel.ProductSelectList = new SelectList(Service.GetProducts(), "Value", "Name");
return View(viewModel);
}
and my view model similar to:
public class IndexViewModel()
{
public SelectList ProductSelectList { get; set; }
public int ProductID { get; set; }
}
With the appropriate part of the view looking like:
#Html.DropDownListFor(x => x.ProductID, Model.ProductSelectList);
This way I'm content that I know where to look if there is an issue with anything and everything has a very specific place.
However, there is no correct way as seems always to be the case with these things. Stephen Walther has a good blog series on MVC tips. In one he talks about the View Model emphasis and although not a SelectList he populates, the SelectList is still data in much the same way his list of products is.
In a classic MVC architecture your Model shouldn't be much more than a container for your view data hence the reason it's often called a ViewModel. A ViewModel is different from the Entity Model(s) that your service layer manages.
Your controller is then responsible for populating your ViewModel from the entity model(s) returned by your service layer.
Due to convenience some developers will use their service layer entities directly in their ViewModels but long term that can lead to headaches. One way around that is to use a tool such as AutoMapper to automate the shuffling of data to and from your ViewModel and entity models.
Here's what a controller might look like. Notice that data such as the SSN does not get exposed to the view since there is a mapping from your Entity Models to your View Model.
public class Customer : IEntity
{
public string CustomerID { get; set; }
public string SSN { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
}
public class CustomerEditViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string PhoneNumber { get; set; }
}
public class CustomerController
{
[AcceptVerbs (HttpVerbs.Get)]
public ActionResult Edit ()
{
Customer customer = _customerService.GetCustomer (User.Identity.Name);
var model = new CustomerEditViewModel ()
{
FirstName = customer.FirstName,
LastName = customer.LastName,
Address1 = customer.Address.Address1,
Address2 = customer.Address.Address2,
Country = customer.Address.Country,
City = customer.Address.City,
State = customer.Address.State,
Zip = customer.Address.Zip,
PhoneNumber = customer.Address.PhoneNumber,
};
return View (model);
}
}
You're right that there are a number of ways to handle this, and that's even before considering variations like MVP, MVVM, et cetera. Since you're asking about ASP.Net MVC in particular, I will defer to Microsoft:
An MVC model contains all of your application logic that is not
contained in a view or a controller. The model should contain all of
your application business logic, validation logic, and database access
logic. For example, if you are using the Microsoft Entity Framework to
access your database, then you would create your Entity Framework
classes (your .edmx file) in the Models folder.
A view should contain only logic related to generating the user
interface. A controller should only contain the bare minimum of logic
required to return the right view or redirect the user to another
action (flow control). Everything else should be contained in the
model.
In general, you should strive for fat models and skinny controllers.
Your controller methods should contain only a few lines of code. If a
controller action gets too fat, then you should consider moving the
logic out to a new class in the Models folder.
Source
I would say your call belongs in the Model.
One thing to keep in mind is that the SelectList class is specific to MVC only. So in my opinion it shouldn't be included in any business logic, and model classes fall into that category. Therefore your select list should be a part of a view model class instead.
This is the way it works in my projects:
Controller method is called
Controller uses repository (business logic, in other words) to get model data
Controller converts the model data if necessary and creates a view model object
Controller passes the view model to the view
The view displays the data in the view model with limited logic to show or hide things, etc
I'd go with option 3. In general, I'll construct my MVC apps such that the controller makes a call to the service to return a model (or collection of models) which are then passed to the view.
I generally keep my models very thin. They are a flattened representation of the data with validation attributes and that's it. I use a service (or model builder) layer to construct the models and do business logic on them. Some folks embed that into the model, but I find that makes for a messy project.
You definitely don't want the view making any calls to your services.
Update...
I'm assuming that this SelectList is your model. If instead it's a part of your model, then you're right, you should put it in your model. I generally don't like to make it a method call, though. I'd have a property on my model:
public SelectList Products { get; set; }
And have my service or model builder class actually populate it. I don't usually have any data-oriented methods on my models.
I'm going with option 1.
Models are the place to make calls to business logic, et cetera.
View - Should display only what the ViewModel already has been populated with.
Controller - the job of the Controller is to direct the traffic coming in (from Web requests) to the Logic that is responsible for handling the request. Hence the term 'controller'.
There are always exceptions to these, but the best place (structurally) is the Model.
I had this problem when I started into MVC and came up with this solution.
The controller talks to a Service Layer. The service layer contains my Domain models and does all the processing for request from the Controllers. The service layer also returns ViewModels to satisfy requests from the controller.
The service layer calls a repository and gets the entities it will need to build the ViweModels. I often use Automapper to populate the ViewModel or collections within the view model.
So, my view models contain all that is needed by the View, and the Controller is doing nothing but handling request and forwarding them to the appropriate service handler.
I don't see a problem with having view specific items like SelectLists in the view Model either.
None of the above.
In my web layer I basically just have html and javascript views. The model shouldn't leak into the view and neither should the services.
I also have an Infrastructure layer which binds the services and model to the views. In this layer there are ViewModels, which are classes that represent what will be displayed on the screen, Mappers, which do the work getting data from services/model and mapping it to the view model, and Tasks, which perform tasks such as Saving, Updating and Deleting data.
It is possible to put a lot of this infrastructure in the Controllers, similar to the example Todd Smith has given above, but I find for anything other than trivial views the Controller becomes littered with code to load data and populate view models. I prefer a dedicated single responsibility mapper class for each view model. Then my controller will look something like
public class CustomerController
{
[AcceptVerbs (HttpVerbs.Get)]
public ActionResult Edit (int id)
{
return View (CustomerEditMapper.Map(id));
}
[AcceptVerbs (HttpVerbs.Post)]
public ActionResult Save(CustomerEditViewModel model)
{
var errors = CustomerEditUpdatorCommand.Execute(model);
ModelState.AddErrors(errors);
return View ();
}
}
I'm torn between option 1 and option 3. I've ruled option 2 out completely as to me that's polluting the view with procedure calls not just presentation layer work.
Personally I would do it in the model and the getter would call the Service layer but I also subscribe to the belief that the model should only contain the information the view needs to render the page, by not fully containing the data in the model at the time you pass it to the view you are breaking this.
Another option here though would be to avoid tightly coupling the view and model by putting a Dictionary of the Products into the view through a Service Call then using the view to transform the Dictionary to a SelectList but this also gives you the ability to just output the information as well.
I think this boils down to a preference as to where you are happy having your logic.

How to avoid needing a VIewModel for every Model

I'm using ASP.NET 4 and MVC3.
Often, I find that I need a ViewModel to display information for my Model. For example, take the following model
class Profile
{
public int UserID { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
There is a requirement to hide the UserID, but to show the UserName, so often time for models that are similar to the one above, I have to come up with a ViewModel with just the UserID changed to UserName:
class ProfileViewModel
{
public string UserName { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
Are there any ways?
Until recently I always passed my models to my action methods as I also thought that creating viewModels with the same property names was duplication (its not). This caused me a lot of pain. I have now been re-educated and almost always use viewModels exclusively in my action methods (of course there will always be situations were it is fine to pass the model directly to the action method).
Have a read of this post which is the one that converted me to using viewModels. This will tell you the following:
The difference between models and viewModels
When each should be used.
How to avoid some security issues with the default model binder.
On top of the information in the linked post you should also consider things such as validation. I had a model that implemented the IValidateableObject interface to ensure the entity was in a valid state before being saved to the database.
In my ASP.NET application I wanted to create a multi-step form that allowed the user to enter the information over a number of pages. The problem I had here was that ASP.NET also uses the IValidatableObject interface during the model binding process.
If you are only allowing the user to enter a subset of the information required for the entity, the model binder will only be able to fill in the information that was given. Depending on how complex your validation is, this can result in the ModelState being marked as invalid as the entire entity is not valid.
The way I got around this was to have a viewModel representing each step each with its own validation. This way you are only validating the properties at each step. Once you get to the final step and everything is valid, I create an appropriate entity using the information given by the user. This entity will only have database-level validation checks performed upon it (field lengths etc.)
My suggestion is not to avoid viewModels but to understand why they are used and embrace them.
No, there isn't, once a member is public, it's public. Now, if the UserID property was internal, then you wouldn't have that problem.
However, one of the aims of MVVM here is to encapsulate logic regarding the interaction of the model and the view. Even if you have the view model and model in separate assemblies and make the UserID property internal, you should still have a view model; if changes come down the line where more functionality is required than simply binding to the model, you are prepared.
Direct access to the model is always a no no.
Additionally, if you really wanted, you could always use T4 templates to auto-generate the code for you (you could use Code DOM on the original CS file) to output your view models for you.
I usually have multiple ViewModels per model - the tradeoff you have to make comes down to this:
Are you comfortable coupling business logic (data annotations, display information, etc...) with your (persistence) models?
Are you comfortable doing all of the hide / display business logic purely within the View and not use the Controller + scaffolding to make those decisions for you?
The downside of creating all of those ViewModels of course is sub-class explosion, but the right way to think about it is in terms of the questions I listed IMHO.

Resources