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:
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'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.
There is a slight workaround in your case I'll share with you, but please note the preconditions:
...then you can do this:
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.View<TModel>
models.But use this approach with caution because it can introduce inconsistency.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With