MVC, Strongly Typed Views and Entity Framework dilemma - asp.net-mvc

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.

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.

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.

What's wrong with passing Linq2Sql objects to Views?

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.

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