What's wrong with passing Linq2Sql objects to Views? - asp.net-mvc

In a previous question, #Darin Dimitrov answered:
In your case the worst thing is that
you are using your Linq2Sql models
inside your views and that's one of
the worst anti-patterns I see people
doing in ASP.NET MVC applications. You
absolutely should be using view
models. That's what views should be
passed from controllers and that's
what controllers should get from
views.
Why is it so bad to pass Linq2Sql objects as Models?

There are a lot of reasons why it's bad to pass Linq2Sql objects as models to your views and controllers, and it would be relatively difficult to cover all of them in a single answer. So, here are my top 3:
Separation of Concerns - Linq2Sql objects have DAL logic embedded in them, which is a violation of SoC. Also, you will likely want to validate data passed from your views, which should be done in the Model (NOT the controller!). However, if you add this logic to your L2S models then you also violate SoC (not to mention the fact that your validations will be wiped out if you regenerate your L2S models)
Encapsulation - Your L2S classes have a lot of members that your view(s) and controller(s) likely do not need access to. A proper model would encapsulate these members to keep them inaccessible.
Maintainability and Reusability - At some point you may decide you want to change your backing store. If you use your L2S classes as models then you'll end up touching a LOT of code to make that change, whereas if you roll your own models then you'll only have to worry about changing your models and nothing else. Also, not messing with your L2S models (see SoC above) means that they're reusable across projects.

In addition to Brian Driscoll's excellent answer, I would add that with LINQ to SQL or the Entity Framework, you don't always know what values actually exist on the objects you've been given. Let's say your view model included a User object from Linq2Sql. You may be tempted to do something like this:
Messages (<%: Model.User.Messages.Count() %>)
Because the Messages property exists on the user object, it's easy to assume that this is totally fine. However, the results of this action aren't entirely clear.
If you have lazy loading enabled, but the context has been disposed, an exception will be thrown.
If you have lazy loading disabled, you'll probably end up with "Messages (0)"
If you have lazy loading enabled, and the context is active, this will cause every single message associated with that user to get loaded into memory, just to figure out how many there are.
On the other hand, if you used LINQ to generate a ViewModel that contains the information you know you'll need to generate your view, it might look like this:
using (var context = _contextFactory.Get()) {
return (from u in context.Users
where u.UserId == userId
select new UserSummary {Name = u.Name, MessageCount = u.Messages.Count())
.Single();
}
This uses a single SQL query to get all the information you'll need for this view, while ignoring any information you won't need (like the entire contents of the user's inbox). If some future developer wants to add information to this view, they're going to have to ensure it's populated on the ViewModel as part of the data-access logic.

Not only Linq-To-Sql objects, but any entity object should not be exposed to the view.
It reveals your data schema to the end user( a hacker might find it usefull)
It violates the separation of concerns principle in mvc.
When your entity objects lazy load inside the view, it is not much different to have used the data access logic inside the view. So the whole point of layering your application is gone.

Related

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.

MVC, Strongly Typed Views and Entity Framework dilemma

I've read quite a few Q & As relating to logic in views within an MVC architecture and in most cases I agree that business logic shouldn't live in a view. However having said this, I constantly question my approach when using Microsoft's MVC Framework in conjunction with the Entity Framework because of the ease of accessibility to foreign key relationships a single entity can give me which ultimately results in me performing Linq to Entities queries inline within a View.
For example:
If I have the following two entities:
Product ([PK]ProductId, Title, Amount)
Image ([PK]ImageId, [FK]ProductId, ImageTitle, DisplayOrder)
Assuming I have a strongly typed Product view and I want to display the primary image (lowest display order) then I could do something like this in the view:
#{
Image image = (from l in Model.Image
orderby l.DisplayOrder
select l).FirstOrDefault();
}
This is a simple example for demonstration purposes, but surely this begins to bend the rules in relation to MVC architecture, but on the other hand doing this in the Controller and then (heaven forbid) jamming it into the ViewBag or ViewData would surely be just as much of a crime and become painful to manage for more than a few different related classes.
I used to create custom classes for complex Models, but it's time-consuming and ugly and I no longer see the point as the Entity Framework makes it quick and easy to define the View to be the primary Model (in this case a Product) and then easily retrieve all the peripheral components of the product using Linq queries.
I'd be interested to know how other people handle this type of scenario.
EDIT:
I also quite often do things like:
#foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder).ToList())
{
<img ... />
}
I'm going the 'custom classes for Models' way, and I agree it's time consuming and mundane, hence tools like http://automapper.codeplex.com/ have been created, to accompany you with this task.
Overall, I'm having similar feelings to yours. Reading some stuff saying it's good to have your domain model unrelated to your storage, then different class for your view model than the domain model, and then seeing that libraries actually seem to 'promote' the easy way (data annotations over your domain classes seem to be simplier than EF fluent interface etc etc).
At least we've got the choice I guess!
Model binding There is also issue that when you want to POST back the model data and store it in the database, you need to be careful and make sure MVC model binders bind all fields correctly. Else you may loose some data. With custom models for views, it might be simplier.
Validation
MVC gives you a way to validate using attributes, when you use viewmodels, you can freely pollute it with such annotations, because it's view specific (and validation should be view/controller action specific as well). When you use EF classes, you would be polluting those classes with unrelated (and possibly conflicting) logic.

Best practice question - Working straight with Linq to sql classes

This is possibly a bit of a stupid question, but I am getting confused due to the ASP.NET MVC book I am currently reading...
Working with Linq-To-SQL it seems to say that it is not good practice to pass the Linq-to-SQL objects straight to the controller, but that each object should be modelled separately first and this should be passed between the controller and the repository.
Say, I have a database of products. Linq-to-SQl creates a product class for me with Name, Price and Whatnotelse properties. I could pass that straight from repository to controller and then view, but instead it seems to recommend that I use and third class, say Product_Entity, with also Name, Price etc. properties and pass that to the controller.
I fail to see the benefit of this approach, except possibly for adding attributes to the properties... But apart from that it seems to have more drawbacks than benefits. Say each product has manufacturer information as well, I don't see how I can model that easily in my third class.
Is this approach really best practice? Or did I misunderstand all that? If so, why is it bad to work straight off the linq-to-sql generated objects? And how do you deal with relationships between objects in y
The huge benefit to this other class you create is that, to use your example, it doesn't necessarily map to either a product or a manufacturer. Think about it like this:
Your Linq to SQL classes are meant for talking in the "data" domain.
Your "data" classes (the ones you're having trouble with) are meant for talking in the "application" domain.
Let's take an example. Suppose in your MVC application you wanted to show a grid of information about products. You want to see their Name, Price (from the Product table) and their Country of Manufacture and Manufacturer name (from the Manufacturer table). What would you name this class? Product_Manufacturer? What if later on you wanted to add properties from yet a third table such as product discounts? Instead of thinking about these objects in purely the data domain, think about them with regard to your application.
So instead of Product_Manufacturer, what about calling it ProductSummaryItem? Each property of the ProductSummaryItem class would map 1:1 with a field shown in your grid on the UI. Your controller would perform the mapping between the information in the data domain (Product, Manufacturer) with the custom class you'd created in the application domain (ProductSummaryItem).
By doing this, you get some awesome benefits:
1) Writing your views becomes really, really simple. All you have to do to display your data is loop through the ProductSummaryItems and wrap them in and tags, and you're done. It also allows for simple aggregation. Say for example you wanted to add a field called ProductsSoldLastYear to your ProductSummaryItem class. You could do that very simply in your views because all it is to them is another property.
2) Since the view is trivial and there's mapping logic in the controller, it becomes much easier to test the controller's output because it's customized to what the view is going to see.
3) Since the ProductSummaryItem class only has the data it needs, your queries can potentially become much faster because they only need to query for the fields that would populate your ProductSummaryItem object, and nothing else. This overhead can become overbearing the more data-domain objects make up your ProductSummaryItem object.
This pattern is called Model View ViewModel (MVVM) and is hugely popular with MVC as well as in frameworks like WPF.
The argument against MVVM is that you have to somewhat reimplement simple classes for CRUD operations. Fair enough, I guess, but you can use a tool like automapper to help out with things like that. I think you'll find fairly quickly, though, that using the MVVM pattern even for CRUD pays dividends, because before you know it, even with simple classes, you'll start wishing you had extra fields which can easily drive your views.

How to handle view model with multiple aggregate roots?

At the moment, i got quite badly fashioned view model.
Classes looks like this=>
public class AccountActionsForm
{
public Reader Reader { get; set; }
//something...
}
Problem is that Reader type comes from domain model (violation of SRP).
Basically, i'm looking for design tips (i.e. is it a good idea to split view model to inputs/outputs?) how to make my view model friction-less and developer friendly (i.e. - mapping should work automatically using controller base class)?
I'm aware of AutoMapper framework and i'm likely going to use it.
So, once more - what are common gotchas when trying to create proper view model? How to structure it? How mapping is done when there's a multiple domain object input necessary?
I'm confused about cases when view needs data from more than 1 aggregate root. I'm creating app which has entities like Library, Reader, BibliographicRecord etc.
In my case - at domain level, it makes no sense to group all those 3 types into LibraryReaderThatHasOrderedSomeBooks or whatnot, but view that should display list about ordered books for specific reader in specific library needs them all.
So - it seems fine to create view OrderedBooksList with OrderedBooksListModel view model underneath that holds LibraryOutput, ReaderOutput and BibliographicRecordOutput view models. Or even better - OrderedBooksListModel view model, that leverages flattening technique and has props like ReaderFirstName, LibraryName etc.
But that leads to mapping problems because there are more than one input.
It's not 1:1 relation anymore where i kick in one aggregate root only.
Does that mean my domain model is kind a wrong?
And what about view model fields that live purely on UI layer (i.e. enum that indicates checked tab)?
Is this what everyone does in such a cases?
FooBarViewData fbvd = new FooBarViewData();
fbvd.Foo = new Foo(){ A = "aaa"};
fbvd.Bar = new Bar(){ B = "bbb"};
return View(fbvd);
I'm not willing to do this=>
var fbvd = new FooBarViewData();
fbvd.FooOutput = _mapper.Map<Foo,FooOutput>(new Foo(){ A = "aaa"});
fbvd.BarOutput = _mapper.Map<Bar,BarOutput>(new Bar(){ B = "bbb"});
return View(fbvd);
Seems like a lot of writing. :)
Reading this at the moment. And this.
Ok. I thought about this issue a lot and yeah - adding another abstraction layer seems like a solution =>
So - in my mind this already works, now it's time for some toying.
ty Jimmy
It's tough to define all these, but here goes. We like to separate out what we call what the View sees from what the Controller builds. The View sees a flattened, brain-dead DTO-like object. We call this a View Model.
On the Controller side, we build up a rich graph of what's needed to build the View Model. This could be just a single aggregate root, or it could be a composition of several aggregate roots. All of these together combine into what we call the Presentation Model. Sometimes the Presentation Model is just our Persistence (Domain) Model, but sometimes it's a new object altogether. However, what we've found in practice is that if we need to build a composite Presentation Model, it tends to become a magnet for related behavior.
In your example, I'd create a ViewFooBarModel, and a ViewFooBarViewModel (or ViewFooBarModelDto). I can then talk about ViewFooBarModel in my controller, and then rely on mapping to flatten out what I need from this intermediate model with AutoMapper.
Here's one item that dawned on us after we had been struggling with alternatives for a long time: rendering data is different from receiving data.
We use ViewModels to render data, but it quickly turned out that when it came to receiving data through forms posting and similar, we couldn't really make our ViewModels fit the concept of ModelBinding. The main reason is that the round-trip to the browser often involves loss of data.
As an example, even though we use ViewModels, they are based on data from real Domain Objects, but they may not expose all data from a Domain Object. This means that we may not be able to immediately reconstruct an underlying Domain Object from the data posted by the browser.
Instead, we need to use mappers and repositories to retrieve full Domain Objects from the posted data.
Before we realized this, we struggled much with trying to implement custom ModelBinders that could reconstruct a full Domain Object or ViewModel from the posted data, but now we have separate PostModels that model how we receive data.
We use abstract mappers and services to map a PostModel to a Domain Object - and then perhaps back to a ViewModel, if necessary.
While it may not make sense to group unrelated Entities (or rather their Repositories) into a Domain Object or Service, it may make a lot of sense to group them in the Presentation layer.
Just as we build custom ViewModels that represents Domain data in a way particularly suited to a specific application, we also use custom Presentation layer services that combine things as needed. These services are a lot more ad-hoc because they only exist to support a given view.
Often, we will hide this service behind an interface so that the concrete implementation is free to use whichever unrelated injected Domain objects it needs to compose the desired result.

Using a View Model + Data Model in ASP.NET MVC to support typed views?

How do most developers handle Typed Views in ASP.NET MVC when dealing with large applications? We are considering putting View-specific models in the Models folder, then putting all domain objects into a separate project. This way our Controllers can easily add the domain object to the typed view, without the domain object needing to be aware of the View layout itself.
For example, if we have an Employee object with:
Id
First Name
Last Name
Status
Then our Employee View might use a ViewEmployeeModel object with:
Employee object
List to populate Status drop-down
etc
Is this a sensible approach? Are there better ways to accomplish the same thing? It seems a little strange since I'd basically have two models (one for the view, one for the business objects), but isn't it better than using untyped views?
I do this almost as a rule, because:
It lets you design the app view-first instead of DB-first, which is nice when working with customer representatives.
Views typically have a much "flatter" object graph than, say, Entity Framework models. LINQ makes it easy to map these.
The views and the data model can evolve much more independently.
It's typically easier to model bind to a flat view model with, say, FK IDs than an entity model which expects fully materialized related objects.
You don't have to worry about accidentally exposing "secret" properties or whitelisting properties for updates.
Don't have the reputation to comment, but Craig is right. It's a variation of the Model-View-ViewModel pattern. There's a good article on it available at Los Techies.
The article also uses the AutoMapper code that mgroves pointed out so you should be able to kill two birds with one stone.
I think this is a pretty sensible approach. One thing that might help you out is AutoMapper.
Seems fine, you have the advantage that the model only contains information needed by the view and not lots of pesky business logic functions / values.

Resources