MVC Models & Controllers where what to write - asp.net-mvc

We have started using MVC framework and now we are bit confused where to write business-logic, in controllers or models?
For the project we are going to use WCF layer as DAL.
People have different views on Model & Controller, and think differently of writing business logic either in 'M' or 'C'.
What is the best practice?
I believe we will be accessing WCF (DAL) service in Model and applying all the business logic or filtering and then Controller accessing the data from Model.

These are my rules:
Controller
Mainly Pageflow . Determines what View is displayed next.
Has access to Services ( ie productService.GetProduct(Model.ProductID) )
Model
I have 2 of them.
POCO-Classes - used by all layers (BLL,DAL)
ViewModel - used by View and Controller for stronly typed views.
View
Hopefully mainly easy HTML
I try to have the layout in a way, that it is possible to have different kind of people work at the project: The frontend guy and the backend guy.
The backend guy will do the Service and Repository.
The Frontend guy will do Controller and Views. He also does ajax.

Try to keep -Business- logic and -Application flow- logic separate. Most people tend to mix those together as -business logic-

Most people keep their business logic in the model and this is considered best practice. Steve Sanderson who has written xVal endorses this method.
As I’ve discussed before, validation rules should go in your domain model, because the role of your model is to represent the workings of your business. It ensures that the rules will be enforced consistently, regardless of whether the UI coder remembers them or not.
Check out his post about xVal that talks about the problem you are discussing.

Do not think that model is supposed to be build from data access logic (wcf service in your case) only. I would recommend you to check out Domain Driven Design, it goes well with MVC. Controllers shouldn't contain any business logic. Controller action method should be ~20 or less lines. But that's just my opinion (made up from countless sources).

Related

Service layer and project structure in ASP.NET MVC 5 without repository and UoW patterns

I'd like to create a good app in ASP.NET MVC 5 using EF 6 Code first concept. I want it to be well-designed i.e. having generally speaking: Presentation, Logic and Data layers separated. I want it to be testable :)
Here's my idea and some issues related with creating application
Presentation layer: It's my whole MVC - view models(not models), views, controllers
I believe that's validation should be done somewhere else (in my opinion - it's a part of business logic) but it's quite convenient to use attributes from the DataAnnotations namespace in ViewModelds and check validation in controller.
Logic layer: Services - classes with their interfaces to rule business logic.
I put there functions like: AddNewPerson(PersonViewModel Person), SendMessageToPerson(...).
They will use DB context to make their actions (there's a chance that not all of them will be relying on context). There's a direct connection between service and db - I mean the service class have reference do context.
Where should I do mapping between ViewModel and Model? I've heard that service is a bad place for it - so maybe in controllers. I've heard that service should do the work related with db exclusively.
Is it right? Is my picture of service layer is good?
Data layer: I've read about Repository and UoW patterns a lot. There're some articles which suggest that EF6 implements these two things. I don't want to create extra code if there's no need for such a behavior. The question is: am i right to assume that i don't need them?
Here's my flow:
View<->Controllers(using ViewModels)<->Services(using Models)<->DB.
**I'm gonna use DI in my project.
What do you think about my project structure?
There is no reason to use a Unit of Work pattern with Entity Framework if you have no need to create a generic data access mechanism. You would only do this if you were:
using a data access technology that did not natively support a Unit of work pattern (EF does)
Wanted to be able to swap out data providers sometime in the future.. however, this is not as easy as it might seem as it's very hard NOT to introduce dependencies on specific data technologies even when using an Unit of Work (maybe even BECAUSE you are)... or
You need to have a way of unifying disparate data sources into an atomic transaction.
If none of those are the case, you most likely don't need a custom Unit of Work. A Repository, on the other hand can be useful... but with EF6 many of the benefits of a Repository are also available since EF6 provides mocking interfaces for testing. Regardless, stay away from a generic repository unless it's simply an implementation detail of your concrete repositories. Exposing generic repositories to your other layers is a huge abstraction leak...
I always use a Repository/Service/Façade pattern though to create a separation between my data and business (and UI and business for that matter) layers. It provides a convenient way to mock without having to mock your data access itself and it decouples your logic from the specific that are introduced by the Linq layer used by EF (Linq is relatively generic, but there are things that are specific to EF), a façade/repository/server interface decouples that).
In general, you're on the right path... However, let me point out that using Data Attributes on your view models is a good thing. This centralizes your validation on your model, rather than making you put validation logic all over the place.
You're correct that you need validation in your business logic as well, but your mistake is the assumption that you should only have it on the business logic. You need validation at all layers of your application.. And in particular, your UI validation may have different requirements than your business logic validation.
For instance, you may implement creating a new account as a multi-step wizard in your UI, this would require different validation than your business layer because each step has only a subset of the validation of the total object. Or you might require that your mobile interface has different validation requirements from your web site (one might use a captcha, while the other might use a touch based human validation for instance).
Either way, it's important to keep in mind that validation is important both at the client, server, and various layers...
Ok, let’s clarify a few things...
The notion of ViewModel (or the actual wording of ViewModel) is something introduced by Microsoft Martin Fowler. In fact, a ViewModel is nothing more than a simple class.
In reality, your Views are strongly typed to classes. Period. To avoid confusion, the wording ViewModel came up to help people understand that
“this class, will be used by your View”
hence why we call them ViewModel.
In addition, although many books, articles and examples use the word ViewModel, let's not forget that it's nothing more than just a Model.
In fact, did you ever noticed why there is a Models folder inside an MVC application and not a ViewModels folder?
Also, ever noticed how at the top of a View you have #model directive and not # viewmodel directive?
That's because everything could be a model.
By the way, for clarity, you are more than welcomed to delete (or rename) the Models folder and create a new one called ViewModels if that helps.
Regardless of what you do, you’ll ultimately call #model and not #viewmodel at the top of your pages.
Another similar example would be DTO classes. DTO classes are nothing more than regular classes but they are suffixed with DTO to help people (programmers) differentiate between all the other classes (including View Models).
In a recent project I’ve worked on, that notion wasn’t fully grasped by the team so instead of having their Views strongly typed to Models, they would have their Views strongly typed to DTO classes. In theory and in practice everything was working but they soon found out that they had properties such as IsVisible inside their DTO’s when in fact; these kind of properties should belongs to your ViewModel classes since they are used for UI logic.
So far, I haven’t answered your question but I do have a similar post regarding a quick architecture. You can read the post here
Another thing I’d like to point out is that if and only if your Service Layer plans on servicing other things such as a Winform application, Mobile web site, etc...then your Service Layer should not be receiving ViewModels.
Your Service Layer should not have the notion of what is a ViewModel. It should only accept, receive, send, etc... POCO classes.
This means that from your Controller, inside your ActionResult, once the ModelState is Valid, you need to transform your ViewModel into a POCO which in turn, will be sent to the method inside your Service Layer.
In other words, I’d use/install the Automapper nugget package and create some extension methods that would convert a ViewModel into a POCO and vice-versa (POCO into a ViewModel).
This way, your AddNewPerson() method would receive a Person object for its parameter instead of receiving a PersonViewModel parameter.
Remember, this is only valid if and only if your Service Layer plans on servicing other things...
If that's not the case, then feel free to have your Service Layer receive, send, add, etc...ViewModels instead of POCOs. This is up to you and your team.
Remember, there are many ways to skin a cat.
Hope this helps.

Implementing application logic on model layer (MVC)

I keep reading that the biggest layer in the MVC pattern should be the model. I've also heard that we should avoid putting logic on the controller layer. However, as my ASP.Net MVC 5 application is getting larger, I see that I'm getting heavy views, heavy controllers, and... extremely tiny models (they're not more than references to my SQL tables).
Yes, I admit, I could never manage to put any logic on my model.
I like the MVC pattern, and my website is working good, but I keep on thinking that I'm surely not doing things right...
Can you show me some useful links about how to write MVC code properly? Rick Anderson's (Microsoft) MVC 5 tutorial is fine, but once again, his models are indeed very tiny...
In my applications I put as much logic as possible in the domain models. On top of that there is an application layer which interacts with the database and domain models to perform application specific operations. The controller actions have as little code as possible and just call methods in the application layer.
In addition I usually have a view model for each view. Any logic that you have making your views "heavy" would go there.
One of the main reasons I try to put as much logic as possible in the domain models is to make unit testing easier. Logic in the application layer usually involves the database, which you will need to mock in order to test. Moving logic to the domain models makes testing easier and makes you code more reusable.
This is a pretty complex issue. I have an in depth blog post on the question if you're interested.
This answer is also pretty close to what I would suggest.
You're missing a service/business layer which should be injected in your controllers though "Dependency Injection". These services do all the heavy lifting.
Having Models without any methods or operations in them is a good thing. You're only storing this info anyway. They basically just get; set; data.
Use extra layer between models and controllers (for example repositories as data access layer).
I strongly recommend using ViewModels-they make code much more organized.
You should Create Some Classes that purely doing business logic and emit ViewModels for MVC view. Controller should respond to actions and the action method delegate the responsibility of getting the model to this business classes.
After some research on this issue, and taking into account some of these answers and comments, I realized that a medium sized MVC project can't rely exclusively on the 3 layered model. As the controller actions become bigger, the developer starts feeling the need of creating a 4th layer: the service layer. Like Gunnar Peipman correctly suggests in the following blog post, "Controller communicates with service layer and gets information about how access code claiming succeeded": http://weblogs.asp.net/gunnarpeipman/archive/2011/06/20/asp-net-mvc-moving-code-from-controller-action-to-service-layer.aspx

How to DTOs fit into the Repository+Service Pattern of MVC Applications?

I'm about a month into MVC and from what I understand, a pretty good approach to app architecture is:
MVC <> Service <> Repository <> Core
Within MVC we have Views, and Controllers to populate viewModels for the controllers. My question is: Where exactly to Data Transfer Objects come in? I'm building a single-page web app and I'm trying to do it right from the beginning.
From the reading I've done, I should use DTOs to "flatten" the Model objects before passing them into the ViewModel. Do they act as a "only data that I need" object that gets passed from the service to the controller, at which point the viewModels are constructed? If so, is it generally true that each model definition (ie Sets, Cards, Users) should have corresponding DTO classes in the Core layer? Any clarifications here would be awesome, thank you for your time!
First of all, about this phrase: "a pretty good approach to app architecture is...": I don't believe there is a single good approach to all apps, and I would prefer always to use the simplest approach (i.e. fewer layers) that could solve your problem at hand.
When you say "Service", it appears to be a whole layer of web services, rather than just some domain service classes; in most cases I've seen with Asp.Net MVC, the controller itself can fulfill the role of a service, thus eliminating the need to add yet another layer. Of course there are exceptions, just be sure your reason to increase complexity is legitimate.
About DTO's and View models: DTO's, like you described, flatten the object model and return "only data that I need". DTO is a more generic term, usually used with web services where you don't know who is the consumer. Think of (Asp.Net MVC) View Models as a more specialized kind of DTO, that returns "only data that THE VIEW needs". Thus, if you don't need an extra layer of services, you also don't need an extra layer of DTO's, just use View Models to flatten the domain classes directly and return them from your controllers.
In fact, for very simple applications, even the separation of Models x ViewModels is overkill - it is possible to use a single Model layer to fulfill both roles, with the help of the ViewBag. I don't know your requirements, so I can't say which is better for you.
Finally, one comment: if you must build a single page application, Asp.Net MVC is not the best tool for the job. I'd recommend using Asp.Net Web Api (only services, no views) at the server and a client mvc framework, such as BackboneJs or AngularJs.

Why should I use view models?

I'm new to developing web apps using ASP.NET MVC. In fact, I'm rather new to developing web apps, regardless of technology.
Currently, I'm working on a project just to get to know the ASP.NET MVC framework better. When reading on SO and elsewhere on the internet, the consensus seems to be that the views should never deal directly with the business objects (i.e. objects implementing business logic and containing associated attributes). Instead, view models should be used. However, this introduces a couple of issues:
Where do I put my validation code?
I need to add code to map between business objects and view models.
In fact, it seems rather cumbersome and I haven't really seen anyone explaining properly why it's a bad idea passing business objects to the views. Could someone please try to explain this (or point to a good explanation)?
Just a clarification; I'm not looking for examples on how to handle the two issues with view models above but simply an explanation on why I should use view models at all.
Where do I put my validation code?
On the view models you should validate everything that's specific to the application like for example the date should be in en-US format culture, ....
I need to add code to map between business objects and view models.
That's why there are tools such as AutoMapper.
Different problems arise when you use directly your domain models in the views:
The views have specific requirements for displaying the data (localization/globalization) so you either end up with spaghetti code in your views or you put this code on your models so that they become less reusable in other applications because you have polluted them with specific presentation stuff
You have different validation requirements based on the view. Let's take for example the case of Add and Update views. In the Add view the Id property won't be needed and it won't be required because you will be inserting a new item. In the Update view the Id property would be required because you would be updating an existing item. It would be difficult to handle those specific validation rules without view models.
The models might contain properties such as IsAdmin and then I am leaving to your imagination the implication of a controller action with the following signature:
[HttpPost]
public ActionResult CreateUser(BusinessObjectUser user) { ... }
assuming that you have hidden this property from the underlying form by not including it.
The business models don't change often whereas the UI could change more often. What if your customer asks you to split your screen in two? The way you present the information changes and the way it is formatted also change. If you use your models directly into the views the spaghetiness of your views becomes worse and worse with every change.
About 60% of the question I am answering on StackOverflow in the asp.net-mvc tag wouldn't have been asked if the OP have used a view model.
Three reasons to why you should use View Models:
Reason 1: Remove logic from your Views
Reason two: Security
Reason three: Loose coupling
Below link may useful:
http://www.codeproject.com/Articles/223547/Three-reasons-to-why-you-should-use-view-models
First off, allowing the Views to have direct access to the Business Objects in ASP.NET MVC introduces some extra security concerns. ASP.NET MVC does a lot of Model binding for you when a user posts a value back to your controller. This can open you up to various kinds of attacks. By introducing a View Model in between, you can be sure that only the fields you are interesting are bound (because the ViewModel will only contain the fields you care about).
As for the other questions:
Where do I put my validation code?
I use DataAnnotations on my ViewModels directly. That allows me to use the Model validation architecture built in to ASP.NET MVC. If there's any validation beyond that I handle it in my controller.
I need to add code to map between
business objects and view models.
True. But using something like AutoMapper can greatly reduce the amount of boilerplate code that you have to write by hand.
MVC is easy to understand and has very little overhead. But those that have used the Model-View-Controller pattern for some time know that it isn't perfect. Not even close. The Model-View-ViewModel pattern offers an interesting alternative.
It is important to understand that the Model-View-ViewModel pattern extends the Model-View-Controller pattern. It isn't a dramatic paradigm shift if you are used to MVC. Even though the advantages of MVVM are subtle, they are profound.
What are some of the advantages MVVM has over MVC?
Better Separation of Concerns
Improved Testability
Transparent Communication

Where are the Business Rules in MVC

Now that everyone is talking about MVC, I notice that the business rules are not being addressed. In the old days of the 3-tier architecture, The business rules were in the middle layer. Where do they fall in the new MVC?
The reason you never see MVC address "Business Rules" is that MVC by and large is a presentation pattern. It's focused on how to structure your application. The Model, for example, can be thought of as a presentation model. The model of your application, which the view then renders.
However, in order to create the presentation model, you generally need to go to your domain models where all your business logic lives. At that point, MVC doesn't dictate where that code physically live. Is it on another tier? MVC doesn't care.
At first brush, I'd say they belong in the model. The MVC Entry on Wikipedia seems to agree: "In MVC, the model represents the information (the data) of the application and the business rules used to manipulate the data".
After all, by 'Business rules' we mean the functional algorithms and logic that encode the domain that your application is involved with, as opposed to input/output related logic. These core business-related logic does not - or should not- change based upon what is being displayed to the user (which is the domain of the View) or the user input (which is primarily received by the Controller).
In my experience, asking this sort of question has been very revealing during the software development process: we found a large number of things that were considered 'business rules' by some people, but turned out to be something else. If it is not a true business rule, it might not belong to the model.
Business rules always live in the model. The model is the bit that you could resuse with a completely different UI. The view is obviously completely dependent on UI choices and the controller has to take data from the model and tell the view to render it.
Putting business logic into the view is bad because it ties the structure to the presentation.
Putting business logic into the controller is bad because it splits your business domain between the data persisted by the model and the rules in the controller.
A quote from a Wikipedia Article:
MVC is often seen in web applications, where the view is the actual HTML page, and the controller is the code that gathers dynamic data and generates the content within the HTML. Finally, the model is represented by the actual content, usually stored in a database or in XML nodes, and the business rules that transform that content based on user actions.
Is there any reason why you cant mix MVC and Ntier? Our application does just that. Our controllers are used for data validation and decide which Business Layer calls to make.
OurApp.Web - Asp.net MVC Project
OurApp.Business - Business Layer Library
OurApp.DataAccess - Data Layer Library
OurApp.Entities - Basically all the 'models' shared by all layers
Business rules should be in the model, NOT the controller. The controller and view are part of the presentation layer.
The model represents the domain's entities and functionality ..
The controller is merely a manager for taking user input and requests, performing actions in/on the model and mapping that to views in the presentation layer. The controller is not just a mediator either, the view OR controller may act upon the model.
This is an anciently posted question, but I like a rules repository to be completely independent of any part of an application. Multiple applications, multiple implementations of a business tier, should be able to access a static rendering of a business rules repository. Simple separation decisions such as this make a migration from desktop -> web, for instance, trivial.
In my architecture, View -> Model -> Controller -> Business Tier -> Rules Repository, i.e. the controller accesses coarse data as presented by the business tier/layer, feeds it to the model which massages it into a presentable form, and the view passively displays it. The business tier, which is re-usable across any presentation format, will have explicit rules and access to a subsystem with implicit rules. By design, each component is ignorant of the details of a component above it.
I think the issue is a matter of definition. It seems to me that the logic for presenting the screens in the order needed is a controller issue and I have seen some projects that use a rules engine to determine the order and what is required input from the user. This is not the same as business rules imho.
You guys are wrong the business rules live within the controller and not the model...

Resources