Is an abstract CRUD controller a good idea? - asp.net-mvc

We're developing quite a big application using ASP.NET MVC and at the beginning we saw that could be useful to have an abstract base controller with common CRUD actions (new, save, delete...) plus a default list action. In our case we have 20+ entities that are managed through this kind of controllers.
That works and avoids duplicating some code and makes the application more homogeneous but when you see a Controller is difficult to see exactly which actions does it implement and it may implement some actions that should not exist. And for example, imagine you want to edit passing the name and not the id, you have to create a new EditByName(name) and even doing that, you still have the Edit(id) action available because it's in the base.
To me the whole thing smells a little bit to me but I've not found any example showing an alternative because the MVC applications I see have a pretty narrow domain. Any advise? Any example? (I does not necessarily be in ASP.NET MVC, the problem I think is quite generic to any MVC framework).

In some respects I think this is a good idea, but in others I think that it's an abuse of inheritance. I do have a common base controller, but it exists because I've refactored common code from my controllers into it rather than being designed a priori. If your entities are enough alike that the code that you're sharing in the base controller outweighs the cruft that you're forced to drag around, then perhaps it's worth it. If, on the other hand, the code that's being shared is rather minimal and simply invokes a private abstract method that does the work (so that you're implementing it in the real controller anyway), I don't know what it buys you. It's not like you're instantiating your controllers directly anyway (except in your tests) so having a common interface beyond that required by the framework isn't all that important.
My vote would be to refactor into the base class those things that are truly common or are cross-cutting concerns and not try to force an "is-a" relationship that may not really exist.

I created a version of what you're suggesting (though admittedly relatively non OOP) and it's worked very well for me.
I've created a MasterController that sets up a db instance and a few other variables. Once I started looking at the similarities in my CRUD actions, I realized this could be abstracted and moved into a method within the master. Two methods, actually.
protected ActionResult DisplayValidateAndEditModel<TModel>(TModel model, string modelPrefix,
string editViewName, string successActionName, object routeValues, string successMessage,
string[] includeProperties, bool acceptFiles
) where TModel : class
and
protected ActionResult DisplayValidateAndEditModel<TModel>(TModel model, string modelPrefix,
string editViewName, string successActionName, string successMessage,
string[] includeProperties
) where TModel : class
The Edit covers Create/Read/Update and Delete is Delete. Listing is a single line in a controller -- i just get a group of models and add to viewdata.
Both methods check if it's a post. If not, they return the view. If so:
edit calls TryUpdateModel and also does some xVal validation. If all is ok, it redirects to the successAction with any routeValues. If not, it shows the view again. includeProperties can be passed so that my controller can specify exactly what can get updates. And acceptFiles adds additional functionality where it looks for a file posting and, if there, puts it in the database and creates a link between the file record and the model.
delete updates the model's Cancel_Date and Cancel_User properties (I have a ICancelable interface) and redirects to the success action

This is one of the things Rails packs with ( along with generating the relevant CRUD views for you ) and it's great for whipping up a very quick application but once you get serious about development it is very unusual for the vanilla CRUD stuff to stay in because the things you need for each table start to change and need further customisation.
That isn't to say it doesn't form a useful foundation and a convenient way of setting things up while you're developing and prototyping - much easier than tinkering about in database fields - but certainly the way it works with Rails you don't expect to have any of those pages in your final administration system.

To me the whole thing smells a little..
The same smell here :-)
It is common pratice to have little code in the controller. Its main purpose is to decide what View is rendered with which Model next.
If you wish to have a common place for all the controller code it shows, that you probably have to much logic in the controller.
Try to move the logik into the Model. Use Filters and CustomModelBinder.

Just a though: As you know ASP.NET MVC supports basic scaffolding like Ruby on Rails. What you may consider is to customize the T4 files used to create the Create, Update, Details Views to meet your specific needs.
http://blogs.msdn.com/webdevtools/archive/2009/01/29/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers.aspx

Related

MVC Pattern - Is this the correct approach for Repository / Unit of Work

I have been doodling and reading and just want to ensure the approach I am taking is correct. I am using MVC5 with EF, implementing the Repository and Unit of Work patterns.
EntityModel -> <- SomeRepository
SomeRepository -> <- SomeController
SomeController -> SomeViewModel
SomeViewModel -> SomeView
SomeView -> SomeController
SomeController -> <- SomeRepository
etc ..
In the controller I am planning on using something like AutoMapper to map the ViewModel to the EntityModel (and vice versa) which can then be passed to my repository / view.
Also, with this approach I am not 100% sure where my business logic should go. For instance, if I have an EntityModel for products and I wanted to add a GetAssociatedProducts method, would this go against the EntityModel or should another tier be introduced so the EntityModel is just a straightforward mapping class to the DB?
Should the ViewModel contain any logic at all? i.e Creating a Dictionary to populate a dropdown on the view based on values from the EntityModel?
I am trying to avoid the issues associated with just starting to code without thinking to much into how which is the reason for this question.
Note: I am also implementing IoC with Autofac but I don't think that's relevant at this point (saying just in case it is).
Well, you're already thinking too much.
First, since you specifically mention MVC, let me just say that the vast majority of what you're talking about is not MVC. MVC stands for Model-View-Controller. In the strictest sense, your model is the haven of all business logic for your application. The controller merely connects your model to your view, and your view merely presents the data to the client in a readable format.
Despite its name, ASP.NET MVC does not truly follow the MVC pattern. You could call it Microsoft's take on MVC. The controller and views track pretty closely (though there is some very noticeable and repugnant bleed-over, such as ViewBag). But, the "model" bit is very unclearly defined. Since, Entity Framework is integrated, most latch on to the entity and call this the model, but entities are really bad models. They're just (or at least should just be) a programmatic representation of a database table: a way for Entity Framework to take data from your table rows and put it into some structure that lets you get at it easily.
If you look at other MVC implementations such as Ruby on Rails or Django, their "model" is more of a database-backed factory. Instead of the class simply holding data returned from the database, it is itself the gateway to the database for that type. It can create itself, update itself, query itself and its colleagues, etc. This allows you to add much more robust business logic to the class than you can or should with an "entity" in C#. Because of that, the closest you can get a true MVC model is your domain or service layer, which isn't really factored in at all by default in ASP.NET MVC.
That said, though, if you're implementing a repository / unit of work pattern with Entity Framework, you're probably making a mistake. Entity Framework already does this so you don't have to. The DbContext is your Unit of Work and each DbSet is a repository. Any repository you create, dimes to dollars, will simply end up proxying your repository methods to methods on your DbSet, which is your first sign that something's not right. Now, that's not to say that a certain amount of abstraction isn't still a good idea, but go with something like a service pattern instead: something lightweight and flexible that will truly abstract logic instead of just creating a matryoshka doll of code that will only serve to make your application harder to maintain.
Finally, your view model (which is actually a rip from the MVVM pattern) should simply be whatever your view needs it to be. If your view needs a drop down list, then your view model should contain that. Whether your view model should generate it, is a slight different question that depends on the complexity of the data involved. I don't think your view model should know how to query a database, so if you need to pull the data from a database then you should let the controller handle that and just feed it to the view model. But, if it's something like a list of months, a enum structure, a numerically static list, etc., it might be appropriate for the view model to have the logic to construct that list.
UPDATE
No, they are actually implementing a repository. I'm not sure why in the world the introductory MVC articles on MSDN advocate this, but as one who fell into the same trap early on, I can say from personal experience, and many other long-time MVC developers will tell you the same, you don't want to actually follow this advice. Like I said, most of your repository methods end up just proxying to Entity Framework methods, and you end up having to add a ton of boilerplate code for each new entity. And, the further you go down the rabbit hole, the harder it is to recover, leading inevitably to some major refactoring once you finally grow tired of the repetitive code.
A service pattern is a lot simpler. There may still be some proxying for things like updates and deletes, where there's very little unique from one entity to another, but the real difference will be seen with selects. With a repository, you'd do something like the following in your controller:
repo.Posts.Where(m => m.BlogId = blog.Id && m.PublishDate <= DateTime.Now && m.Status == PostStatus.Published).OrderByDescending(o => o.PublishDate).Take(10).ToList();
While with a service you would do:
service.Posts.GetPublishedPostsForBlog(blog, limit: 10);
And all that logic about what is a "published" post, how blog is connected to post, etc., goes into your service method instead of your controller. The other big difference is that service methods should return fully-baked data, i.e. a list type rather than a queryable. The goal with a service is to return exactly what you need, while the goal with a repository is to provide an endpoint to query into.

Why do we use ViewModels?

I have recently started working as a web developer. I work with ASP .NET MVC 4 and NHibernate.
At my work-place, we are strictly made to use viewmodels to transfer data to and fro between a controller and a view. And the viewmodels are not supposed to contain any object of a model.
I understand that it is a sort of a tier between the controller and the view.
But I find it repetitive and redundant to write a viewmodel class even if we can directly send the model's object to the view (in most cases).
For example, if i want to display an order i can do this in the controller's action -
return View(Repository.Get<Order>(id));
But instead, I have to write a viewmodel, fill it with the fetched order and then pass it to the view.
So, my question is, what purpose does writing viewmodels serve when we can use the model's object as it is?
For smaller projects, you're right. I hear your argument and sympathise - however there are good reasons for this, drudged and repetitive work, especially in larger and more complicated applications:
It's essential to perform all processing within the Controller's action. However in the example you've given, the Repository.Get method might return a lazily-evaluated IQueryable object, which would mean the DB wouldn't be hit until the View is evaluated. For a variety of reasons this is bad. (A workaround is to call .ToList while still in the controller).
"A view should not contain any non-presentational logic" and "You should not trust the View" (because a View could be user-provided). By providing a Model object (potentially still connected to an active DatabaseContext) a view can make malicious changes to your database.
A View's data-to-display does not always map 1:1 with its Model's data, for example consider a User Details page:
A User's EF Model object represents its entity in the database, so it probably looks like this: User { UserId, UserName, PasswordHash, PasswordSalt, EmailAddress, CreatedDate }, whereas the fields on a "User details" page are going to be User { UserId, UserName, Password, ConfirmYourPassword, EmailAddress }, do you see the difference? Ergo, you cannot use the EF User model as the view model, you have to use a separate class.
The dangers of model manipulation: if you let ASP.NET MVC (or any other framework) do the model binding to the incoming HTTP POST Request then (taking the User details example above), a user could reset anyone's password by faking the UserId property value. ASP.NET will rewrite that value during binding and unless you specifically sanitize it (which will be just as drudgeful as making individual ViewModels anyway) then this vulnerability will remain.
In projects with multiple developers working in a team situation, is is important that everything is consistent. It is not consistent to have some pages using bespoke ViewModels but other pages using EF Models because the team does not share a concious mind, things have to be documented and generally make-sense. For the same reason a single developer can get away without putting excessive XML documentation in his source code, but in a team situation you'll fall apart if you don't.
There is a slight workaround in your case I'll share with you, but please note the preconditions:
Your views can be fully trusted
Your views contain only presentational logic
Your application is largely CRUD
Your views correspond 1:1 with each EF entity model (i.e. no JOINs)
Your views only deal with single Simple models for POST forms, not Complex models (i.e. an object graph)
...then you can do this:
Put all one-way, non-form-related data into your ViewData collection, or the ViewBag in MVC 4 (or even a generic ViewData<T> if you're hardcore). This is useful for storing HTML page titles and sharing data with Master pages.
Use your fully-evaluated and loaded EF models as your View<TModel> models.
But use this approach with caution because it can introduce inconsistency.
Well, i'm starting to think the pragmatic approach to every problem is required and not to just subscribe to the purist architectural standards out there. Your app may be required to run in the wild and be maintained by many developers serving a large set of client etc. and this may direct or drive your architecture.
The ViewModel is essential when you want a separation of concerns between your DomainModel (DataModel) and the rest of your code.
The less dependencies you have between the Model, View and Controller the easier down the line it will be to make changes to the DomainModel without breaking the interface contracts in the View and Controller etc. etc. But once again it's something to be pragmatic. I like the approach as code re-factoring is a big part of system maintenance - refactoring may include a simple spelling mistake on a property of a Model - that change could ripple through the code to the Contract level if the dependencies are not separated; for example.
The ViewModel is used to translate the data between your DomainModel and you Views
A simple example of a datetime stored in Informix has to be translated to a .Net DateTime. The ViewModel is the perfect place to do this translation and does not force you to put translation code in all sorts of unwanted places.
One attribute of a good design [of anything] is the ability to replace or modify a part of the implementation with little or no affects to the rest of the parts of the system. But this takes effort and time to achieve - it's up to you to find that practical balance between a perfect design and a design that is just enough
But yeah, there are many other good reasons to use certain patterns - but the bottom line is this:
Nothing forces you to use ViewModels... ASP.NET MVC won't force you. Take advice from the pragmatist inside you.
If you use same Models as your ViewModels, your application should be very small and simple and should contain only CRUD operations. But if you are building large or enterprise applications with large teams (with two or probably more developers), you should have concepts like Dependency Injection, Services, Repositories, Façades, Units of Work, Data Access Objects etc.
To simplify your mapping needs between Models and ViewModels, you can use AutoMapper
https://github.com/AutoMapper/AutoMapper
or install with nuget
Install-Package AutoMapper
According to me, it is essential to have one more layer(ViewModel) on top of Model layer for complex applications that performs most of the CRUD operations because it has following advantages:
To establish loose coupling between Model and Controller. So that any DataModel related modifications will not be affected to Controller.
If you've implemented your application's ViewModel layer correctly
by providing maximum level of IOC(Inversion of Control) via
DI(dependency Injection using Unity/other frameworks), etc., it will
also help you to MOQ your ViewModels(dependencies) for testing only
the controller's logic.

In MVC3, should I have separate "edit" models vs. "display" models?

With MVC3, should I design my view models such that there is one that is bound to the view (DisplayModel), and one that is posted back to the controller (EditModel)?
To clarify, I am not asking about data models vs. view models -- I know it's not good to bind my views/controllers to data/domain models.
Nor am I asking about sharing one model across two separate views, one view that is used for displaying the data, and another view that is used for editing the data.
Rather, I am asking about one view that is used for editing data, and the model that is bound to the view vs. the model that is bound to the controller action.
In other words, if this is my view:
#model MyApp.Models.CustomerModel
Should my controller action look like:
public ActionResult Index(CustomerModel model)
Or:
public ActionResult Index(CustomerEditModel model)
At one point, we were doing the latter (separate). But lately, we've started doing the former (shared).
The reason for this change was because:
With MVC3 unobtrusive validation, if I'm using DataAnnotations on my model for validation, this is needed in both models if they are separated (on the display model to map client-side validation, and on the edit model for server-side validation).
As our application matured, we realized that our display and edit models were 95% identical, with the exception of the select lists that were in our view models. We've now moved these to a shared class and are passing these in via the view now.
But I've seen some other discussions that point to having shared models for view/controller to be a bad idea, and that it violates separation of concerns.
Can someone help me understand the tradeoffs for these two approaches?
I've seen perfectly good arguments for and against, it just depends what works best for your application. There's no one size fits all approach that can be applied!
If you haven't read it Jimmy Bogard has written a very good post about how his team does MVC here, which covers this topic.
I agree with rich.okelly's answer that there's no right approach.
There are a couple of concerns I have with using one model, though.
It's going to be very to always use one model without having unneeded properties when the view needs to display a selectable list of objects. The model will need to have the list of objects as well as a property to accept the POSTed value the user chooses. These unneeded properties add a small amount of code clutter and overhead.
(One way around this is to have the model contain only selected ID and have HTML helpers to build the lists.)
Another concern is more related to security.
A common scenario is displaying information in a form that should be considered read-only.
In the case of a ViewModel and an EditModel, the EditModel will only contain properties that are expected to be POSTed, whereas the ViewModel will contain all of the properties.
For example, if a form displays a user's salary, a user will be able to POST a 'salary' and have it bound to the ViewModel's Salary property automatically by MVC.
At this point, something has to be done to ensure it doesn't end up in the database. It could be if/else logic, a Bind attribute, Automapper logic or something else, but the point is that it's a step that could be overlooked.
When considering the lifespan of an application, I like the explicitness of the EditModel over time.
These concerns don't mean that two models are good and one model is bad, but they should be considered when choosing a design.
If the properties are the same for display and edit view models I see no reason to have separate classes.
I think you'll find that it's hit or miss no matter what way you go but if you can take the path of easiest maintainability then you should do that. In my experience, having a single model is much easier to maintain, obviously, but it seems that there is always some business decision that is made that forces me to split the models. If you're in that 95% then I think you are in really good shape. Your application, from a maintainability perspective related to your models, will be easy to maintain. When a change comes along, you have one place to make that change, for the most part. The issue I always seem to run into is scaling business changes across multiple models. Copy/paste issues, or simply forgetting about some property somewhere, always seems to hurt me because of the multi-model issue.
we realized that our display and edit models were 95% identical, with the
exception of the select lists that were in our view models. We've now
moved these to a shared class and are passing these in via the view now.
Are they 95% identical in data and operations or only in data? Remember that classes encapsulate data and behavior.
If they are 95% similar in properties but have totally different operations you might benefit from splitting them in two classes. Or you might not :)
As others pointed out there is no one-size-fit-all answer and in your case it seems that one class is OK...but if you start noticing that the behavior on each of them is unrelated don't be afraid to rethink you approach.
No - one view model for both directions. Mixing it up is not only harder to follow, but one could easily inject invalid values into the page that then get automatically bound. I could overwrite your customerid (or create one) for example.
Inherit from a base view model if you must or don't rely on data annotations at all and use the fluent api on your model save.
A great link (somewhat unrelated but the auto map is nice)
edit
(sorry someone else previously posted this below I just realized)
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
Also
ASP.net MVC - One ViewModel per View or per Action?
You (IMHO) should be generally binding to your method specific VieWModel rather than a shared view model. You could get caught in a trap of missing properties, etc. but it may also work just fine for you.
Use auto mapper to go between both. Jimmy also has a nice AutoMap attribute when returning to the View. Going back the other way I would not use a CustomerModel in general as there may be fields required in there that are not coming from my say, create view. For example a customer id may be a required field and for a "create" action it won't be present. But - if you find in the most of your cases this to actually work for you, then there is no reason at all not to use it.

MVC: I need to understand the Model

I've been working with the MVC pattern for a while now, but I honestly don't feel like I truly understand how to work with and apply the "Model" ... I mean, one could easily get away with using only the Controller and View and be just fine.
I understand the concept of the Model, but I just don't feel comfortable applying it within the pattern... I use the MVC pattern within .NET and also Wheels for ColdFusion.
"the Model represents the information (the data) of the application and the business rules used to manipulate the data" - yes, I get that... but I just don't really understand how to apply that. It's easier to route calls to the Controller and have the Controller call the database, organize the data and then make it available to the View. I hope someone understands where my confusion resides...
I appreciate your help in advance!
Look at it like this. When your client requests a page this is what happens (massively trimmed):
He ends up at your controller
The controller gets the necessary data from your model
The controller then passes the data to the view which will create your HTML
The controller sends the HTML back to the client
So client -> controller -> model -> controller -> view -> controller -> client
So what is the model? It is everything that is required to get the data required for you view!
It is services
It is data access
It is queries
It is object mapping
It is critical 'throw exception' style validation
Your controller should not be writing your queries if you are sticking to the pattern. Your controller should be getting the correct data required to render the correct view.
It is acceptable for your controller to do a few other things such as validating posted data or some if/else logic but not querying data - merely calling services (in your model area) to get the data required for your view.
I suppose it's just what you decide to call the different bits in your application. Whichever class you use to pass information from the Controller to the View can be seen as/called "The Model".
Typically we call Model our entity classes, and we call View Model the "helper" classes, for lack of a better word, we use when a "pure" entity (i.e., one that will be stored in the database) doesn't suffice to display all the information we need in a View, but it is all mostly a naming thing.
Your model classes shouldn't have any functions; ideally a model class will have only properties. You should see model classes as data containers, information transporters. Other than that they are (mainly) "dumb" objects:
// This would be a model class representing a User
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
How do you actually pass information (whatever that might mean in your context) form your controller to your View and vice versa? Well then, that's your model. :)
Here is the way I have explained before:
Controller: determines what files get executed, included, etc and passes user input (if any exists) to those files.
View: anything that is used to display output to user.
Model: everything else.
Hope that helps.
Model is the code representation of your base Objects. While some less data-intensive systems may be light on the model end of MVC, I am sure you will always find an applicable use.
Let's take a contrived (but realistic) example to the usefulness of a model:
Say I am making a Blog. My Blog has Post objects. Now, Posts are used in and around the site, and are added by many users in the system. Our system was coded for people to enter HTML into their posts, but low and behold, people are starting to add pasted text. This text uses "\n" as the newline character.
With a model, this is a relatively simple fix. We simply make a getter that overrides postText:
public function get postText() {
return this.postText.replace("\n", "<br />");
}
Suddenly, we can affect behavior across the entire site with a few lines of simple code. Without the implementation of a model, we would need to find and add similar functionality where ever postText is used.
The Model in MVC is all about encapsulation and flexibility of a codebase as it evolves over time. The more you work with it and think about it in this manner, the more you will discover other cases that would have been a nightmare otherwise.
--EDIT (you have added to your question above):
Let us take this same example and use your Controller calling the database. We have 9 Controller classes for vaious pages/systems that use Post objects. It is decided that our Post table needs to now have a delete_fl. We no longer want to load posts with delete_fl = 1.
With our Post model properly implemented, we simply edit the loadPosts() method, instead of hunting down all the cases across the site.
An important realization is that in any major system, the Model is more of a collection of files than a single monolith. Typically you will have a Model file for each of your database tables. User, Post, etc.
model: word, sentence, paragraph
controller: for (word in sentence), blah blah... return paragraph
view: <div>paragraph.text</div>
The idea is to separate the concerns. Why not just have the controller logic in the view as well? The model represents the business objects, the controller manipulates those objects to perform some kind of task and the view presents the result. That way, you can swap an entire view for a different one and you don't have to rewrite the entire application. You can also have people work on different layers (model, controller, view) without affecting the other layers to a significant degree.
By combining the controller and the model, you are making your code less maintainable and extensible. You are basically not performing object-oriented programming as you are not representing the things in your database as objects, you are just taking the data out and sending it to the view.
The model contains business logic (i.e. significant algorithms) and persistence interaction - usually with a database. The controller is the MVC framework: Wheels, Struts, .NET's MVC approach. The view displays data that the controller retrieves from the model.
The big idea going on with MVC is that the view and model should be unaware of the controller - i.e. no coupling. In practice there's at least some coupling that goes on, but when well done should be minimal, such that it allows for changing the controller with low effort.
So what should be happening is a request hits the controller, typically a front controller, where there should be some glue code that you've written that either extends some controller object or follows some naming convention. This glue code has the responsibility for calling methods on the correct service layer object(s), packing that data inside of some sort of helper - typically an Event object - and sending that to the correct view. The view then unpacks data from the Event object and displays accordingly.
And when done well, this leads to a domain model (a.k.a. model) that is unit testable. The reason for this is that you've divorced the algorithms from any framework or view dependencies. Such that you can validate those independently.

When is it right to use ViewData instead of ViewModels?

Assuming you wanted to develop your Controllers so that you use a ViewModel to contain data for the Views you render, should all data be contained within the ViewModel? What conditions would it be ok to bypass the ViewModel?
The reason I ask is I'm in a position where some of the code is using ViewData and some is using the ViewModel. I want to distribute a set of guidelines in the team on when it's right to use the ViewData, and when it's just taking shortcuts. I would like opinions from other developers who have dealt with this so that I know my guidelines aren't just me being biased.
Just to further Fabian's comment; you can explicitly ensure viewdata is never used by following the steps outlined in this article. There's really no excuse not to use models for everything.
If you have no choice but to use ViewData (say on an existing project); at the very least use string constants to resolve the names to avoid using 'magic strings'. Something along the lines of: ViewData[ViewDataKeys.MyKey] = myvalue; Infact, I use this for just about anything that needs to be "string-based" (Session Keys, Cache Keys, VaryByCustom output cache keys, etc).
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
I personally never use ViewData, everything goes through the Model, except when im testing something and i quickly need to be able to see the value on the view. Strongtyping!
In terms of ASP.NET MVC 2, ViewModel pattern is the preferred approach. The approach takes full advantage of compile time static type checking. This in combination with compiling mvc views will make your development work-flow much faster and more productive since errors are detected during build/compile time as opposed to run time.

Resources