Your confusion is understandable. Different MVC frameworks have different approaches when it comes to models: some encourage lightweight models, while others welcome models which contain a lot of information.
In ASP.NET MVC, the common practice I observe in many projects is the following:
Models don't contain business logic. In other words, they don't perform anything which involves business rules—this is the task of a controller and the classes used by the controller.
Models don't contain elementary logic which is usually performed by a view. For instance, if the page should display a date in a human-friendly format, such as “November 15th, 2013”, the controller will just use
DateTime object which will remain as-is in the model. It's the view which will be in charge of the conversion from
DateTime to a specific format (eventually using localization).
Models don't access database directly. This may be obvious for you, but the predecessor—ASP.NET, had often SQL queries within the templates, something which would be considered insane by most developers today.
Models can contain lazy
IEnumerable<T> elements which lead to the database; neither the model, nor the view are defining how the data is loaded, but still, the loading itself is postponed until the view is displayed, instead of being done by the controller.
Remains obviously the data itself, that is the data loaded by the controller and transferred to a view through a model. In a model, you'll generally find all the data required to generate the page, except the static content. For instance, on a web page which displays the products, the model could contain:
- The list of products (in a form of a lazy
- The information about the user, if the user is authenticated,
- The cart,
and won't contain elements such as:
- The logotype of the website,
- The site menu,
- The footer with copyright notice,
since they can reside in the view.
Model, ViewData, ViewBag and TempData
Since the release of the DLR, it is not unusual to see data in places other than the model, resulting in more confusion. Even the ASP.NET MVC demo project moves a lot of info from the model into the ViewBag.
The choice here is basically the same as the choice between static typing and dynamic typing, with one difference.
What is the same is that you can if you want move everything to ViewBag and avoid using a model, or keep everything in the model and avoid using the ViewBag: in a case of a model, you have the benefit of static typing, which often means stricter code with bugs found at compile time instead of run time.
For instance, if you are expecting a date in your model and your view is extracting information from this date (such as displaying it in humanly readable format), the controller cannot possibly pass a string. Visual Studio will alert you by underlining the string, and if you try to compile, you'll see an error.
If, instead, the date is in the ViewBag and instead of a
DateTime object, you put a string, Visual Studio will be fine with that, and the compiler won't tell you anything. You'll have to wait until you run the page to see that something went wrong.
The difference, on the other hand, is that ASP.NET MVC's views have a special status of being second-class citizens. Since by default, they are not compiled, it's very easy to make mistakes in the views themselves (such as expecting a
DateTime while the model indicates that it contains a
This means that there is nothing wrong to heavily rely on the dynamic aspects of ViewBag in ASP.NET MVC. If you know that your model and your view will change a lot, go with the dynamic ViewBag. If you know that the model is well defined and is not subject to change unless the requirements change, the real, statically typed model would probably be a better choice.
Another aspect which should be noted is performance. If you're building a large scale web application, you should definitively compare the performance of statically-typed models with the performance of the dynamic ViewBag. I remember that my benchmarks for a project which had nothing to do with ASP.NET MVC showed that switching between static types and
dynamic has practically no difference in terms of performance, but still, make sure you do the actual benchmarks.