Controller or model: who should implement business methods in MVC? - asp.net-mvc

I read from here:
http://www.dotnetjohn.com/articles.aspx?articleid=287
the Controller represents the application's business logic. The Model is that component that maintains the state of the entities.
But if I read the MVC original paper it doesn't the same thing in my opinion:
http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf
As I understand the controller is just like a traffic cop, model since it represents knowledge should implements the business methods.
What's your view ?

IMHO it's the model that should implement the business methods used by the controller. For me the model is a set of business objects and service methods which represent the operations with those objects. MVC is just a pattern. For example if tomorrow you decide to change the pattern and use something else, go ahead, no problem, but you shouldn't change your business models, they are at the hearth of everything.

In MVC applications that I work on, business logic is encapsulated in a Domain assembly - which is shared across a number of applications. The domain is orchestrated by the controller and I use a dumb "ViewModel" to pass data between the controller and each view.

Related

MVC project setup at the enterprise level. What's expected?

By reading at several articles posted here, I get mismatched information about how to properly configure a project.
I am looking for advise about how the pros do it at the enterprise level.
I see different schools of though about this, some people design in a truly N-Tier fashion, others prefer to use EF Code First directly in the MVC application and have FAT models and sort of have one big MVC app with logical separation of concerns, etc.
So for a mid-size project this is my set up and I want to ask for your opinions about it.
MVC application
Models -- Here my models have just what the view needs, validation logic, etc. These models are designed to pass data between the controller and views only.
Controllers -- Call the service layer where business logic lives and gets domain models back if needed. Converts domain models into view models and vice-versa.
Service layer
This is were the business (domain) logic lives.
The service layer is also in charge of communicating with the data layer to perform CRUD operations.
The service layer returns domain models to the controller in the MVC application and also expects domain models when invoked.
Data Repository layer
The data layer is a thin wrapper around EF and performs CRUD operations.
usually I will have a Code First approach where entity models are created for me by EF.
I convert the EF code first models to domain models and return these to the service layer.
The data layer also expect domain models from the service layer that in turn I convert to EF code first models and persist to the DB.
Domain Model layer
These are the domain models that are used and shared thorough the applications layers.
What's best design?
What's expected at the enterprise level?
There's nothing particularly wrong with the approach you've laid out. However, I do see it as overly complex. Your repository layer, in particular, is a totally unnecessary level of abstraction. You could simply just roll the EF stuff into your service layer and call it a day. Having to convert the entity into a domain model and then to a view model, is frankly, a pain. Just map your entity to your view model and back.
The only thing you should really bear in mind is that ASP.NET MVC very loosely follows the MVC pattern. There's no such thing as a true MVC Model, and trying to force something like an entity class into that mold is a huge mistake. Your Model is the combination and interaction of your entity class, view models that represent that class, and the querying logic you tuck away in your service layer.
I would like you to suggest have these layers in your project ----
Entites Layer--
it should contains only all your poco classes in a model folder.Nothing else
Data Layer----
It should contain Db interactions logic.
Also your Dbcontext class should reside in this.
You may use Repository Pattern and unit of work pattern for better seperation of concern.Use dependency injection to resolve dependencies using Unity Container(there are many other container also available).Please have a look on these design pattern and container.there are many articles available on net for this.Simply go through them thoroughly.
Service Layer ----
It should contain only service methods to call into your controller as your controller should not directly talk to data Layer.Its a much better approach and prevent your business logic from being exposed to external attacks.
MVC Layer or UI layer ---
It should contain only the controllers whose work is to call services and business logics inside them.
and View folder where we have all the views to be shown to the end users.
Its a pretty big question.I hope may be u get some idea from this.

Is the DataContext part of Model in MVC or a part of Controller?

working on asp.net MVC from quite some time now
today stuck on a theoretical problem
going through some sample code on MSDN
I read something like this
public class SomeController()
{
public ActionResult SomeAction(SomeModel model)
{
var dataContext = new SomeDataContext();
//basic CRUD operations on data context
//
}
}
here the database obviously is being accessed through the controller and by theory is incorrect
is there something wrong with this example or my definition of what a model and what a controller is needs to be refreshed
UPDATE:-
or there is a possibility that every where on MSDN Models and ViewModels are considered equal
intro
MVC design pattern is quite old. It was originally defined for Smalltalk-80 applications, when "web" was two guys sending ping between universities. Since then it has evolved quite a lot.
The core principle behind MVC design pattern is Separation of Concerns. The pattern separates presentation from business logic. Presentation layer contains mostly views, controller, templates, viewmodels and presenters (depending on which flavor of MVC-inspired patterns you use), while business logic is ends in the model layer.
The model layer, while not strictly defines in the pattern, in ASP.NET MVC consists of services and all the structures that are used by service (including the Model Objects, better known as domain objects).
regarding the question
It is quite common to see DataContext uses in controllers, when you are looking for basic MVC tutorials. MVC architecture is meant of large scale applications, and in a Hello-World example a fully realized MVC architecture would look like just bloat.
The examples sacrifice code separation for sake of simplicity. The interaction with DataContext is basically storage logic, which is one of tasks that model layer handles. When used in controller, it means that your model layer has begun leaking in the presentation layer, and you end up with "Fat controller, skinny model" problem.
In a real world application the DataContext would be part of structure that deal with persistence within model layer. Probably as part of data mappers, if you opt to write them manually.
regarding "update"
The model (I suppose in this case you meant Domain/Model object) is from completely different application layer then ViewModel.
As the name implies, in MVVM pattern the ViewModels replace the Controllers. ViewModel acquired data from model layer, and then transforms it in such a way that is usable for View.
This pattern is best used (if you are really using MVVM) in situation when you do not have full control over behavior over Views or/and Model layer. For example: if you were hired to build an alternative frontend for SAP or when the view is actually some form of hardware device, which expects specific type of input.
The Models are typically the data classes (representing the database tables). The View Models are typically referred to as classes that have been created in order to use them in the view for presentation purposes.
You wouldn't be able to use the DataContext on a View Model in the above case, but you can use it perfectly fine with the above mentioned Model classes (also called DTO classes).
MVC is a GUI pattern, just like MVP or MVVM, it has nothing to do with data access and persistence. It's true that many simple CRUD applications are not much more that MVC and an underlying database, but in more complex applications MVC would be part of the presentation layer.
The DataContext as an O/RM belongs to the infrastructure layer, not the GUI. In MVC the Model can be understood as ViewModel, yes.
Nevertheless the controller can use the DataContext or any other means to retrieve this model from the underlying data store.

ASP.NET MVC - Model can have business logic?

I read a couple of articles which defines domain model (as in MVC) as something that holds business logic. I never considered a model to hold any methods other than the model properties.
I would like to know if actually there is a thought which supports having functions and business logic in the domain models.
Thanks in advance.
Of course business logic should be inside domain models. But, domain models are more than just entity framework entities. Domain models consists of many small classes which reflects business domain.
In my typical MVC application, I usually split some type of business logic into these (but not limited to):
ViewModels which responsible for model for view.
Controllers which is thin and responsible for application flow.
Simple business logic such as required field can exist as attribute within entity framework model or ViewModels.
Complex business logic such as place order, booking ticket are promoted to be its own class such as PlaceOrderOperation or PlaceOrderCommand.
Simple query logic might be inside the Controller or short extension method to DbSet<Entity> type.
Complex Query also promoted to its own class such as GetMostPorpularProductsQuery assuming that the query is complex.
Infrastructure components may be extension to Entity Framework or MVC components such as ActionFilter, CustomRoute, CustomTemplate or its own classes such as EncyptionHelpers etc.
Conclusion
Building domain Model is more than just creating classes prefix with BusinessLogic such as UserBusinessLogic or with Services such as UserServices. It should consists of many small classes which responsible for one thing. Of course, you would require some usage of design patterns, choice of frameworks, infrastructure components such as error handling, localization, caching, etc.
Welcome to the trade-off world. :)
An MVC Model can indeed have business logic. MVC responsibilities been discussed in more depth here and here is a discussion on anemic domain models - this might help clear things up for you?
From MSDN:
Models, which is provided for classes that represent the application
model for your MVC Web application. This folder usually includes code
that defines objects and that defines the logic for interaction with
the data store. Typically, the actual model objects will be in
separate class libraries. However, when you create a new application,
you might put classes here and then move them into separate class
libraries at a later point in the development cycle.
What might be confusing the issue is that many ASP.Net MVC implementations use View Models, which are classes used to transfer presentation tier data between View and Controller.
In a typical large project setup, we usually delete the Models folder, and instead move our EF data layer, Entities, and business / service logic into separate assemblies entirely.
Based on my experience best place to place business logic is layer between controllers and models. Try some popular patterns, like repository or tasks/commands.

Having MVC controllers light and models heavy

I have heard that the controller should be kept light and models heavy.
I am somewhat confused about the best practice on what should be kept in the controller and what should be kept in the model.
In our organization, we use Entity Framework where and put the tables there.
For the controller, we use LINQ and then send the info over to the view.
Kind of confused on what code should be in the Controller and in the Model.
DisclaimerThe whole topic is a giant mess. Especially when it comes to Web MVC. For all practical purposes it is impossible to use classical MVC pattern for web, because the view should be observing model. Theoretically you could implement something like that with WebSockets, but keeping a persistent model for each user is not a realistic solution.
Here is what you must know about MVC
The most important idea in both classical MVC and MVC-inspired patterns Separation of Concerns. It divides the application in two major layers:
Presentation layer
Governs the user interface. It deals with both creation of the interface and reacts to the user's manipulation of this interface. This interface might be GUI for a desktop application or HTML web page, but it also can be REST API or receiver-responder on a Mars rover. This is why a web application can implement MVC pattern in both frontend and backend.
The mandatory parts are views and controllers, but, in context of web, fully realized views usually also use multiple templates to create the interface.
Model layer
This is where all the business rules and logic lives. The M in MVC is not a single entity. Instead it is a layer, which contains different structures. Some of those structures are also responsible for interaction with storage.
What are the responsibilities of controllers ?
Controllers are part of presentation layer, which deals with user input. In context of web-based implementations, you will usually have 1:1 relationship between views and controllers, where controller receives the requests from browser and, based on the content of said requests, alters the state of model layer and view.
If you are using classical MVC or Model2 MVC, then that is the extent of controllers responsibilities.
In MVP and MVVM patterns, where you have a passive view, controller-like structures are responsible for acquiring information from model layer and passing it on to the current view instance. This post might provide some additional details on the MVC-inspired patterns.
But the controller is in no way responsible for any form of business logic. If it was, it would mean, that you have a leaking abstraction, because the structures of presentation layer would be doing work, which should be in the model layer.
Usually the controllers will the be simplest structures in you application.
What about the model ?
As mentioned before, model is a layer, which encompasses all of the domain business logic and related functionality. This layer , just like presentation layer, is made up from multiple groups of structures:
Domain Objects[1]
These structures are usually what people mean, when talking about "models". They are also known as model objects or business objects. This is where most of domain business logic ends up.
Data Storage Structures
This group would contain all of the classes, which abstract the interaction with storage (SQL databases, caching systems, noSQL, remote SOAP or REST APIs). They will usually implement some variation of data mapper or repository pattern , but you could be using some other solutions too, like unit of work. The implementation details are not so important. What is important is that they let you store data from and retrieve information into your domain objects.
Services
Or you could call the "components". There are high level abstractions in your model layer, which facilitate the interaction between domain objects and storage structures. The usually represent large chunks of model layer, like "recognition service", "mailers", "article management", and will provide the interface for presentation layer to interact with.
That's something of a religious debate.
Some like as little as possible code in their controller and other as little as possible in their model.
Do what feels natural to you in the project, but be consistent within it.
All else is dogma you can pick an example either way and make a case.
Model is the core of your application. It is best to think of models as of your business entities. Do you want to create a view of an invoice? Then Invoice be your model, it represents the underlying object.
Controller is just a way to handle requests from a client, retrieving the data from database (or updating them) and flushing out the responses.
Your thoughts about the application design should be model-centric, that's the important part.
In simple terms, Model represents the underlying data that your application will be using. It is to be designed in a way that it can be used across different applications.
For example, A model to represent News data can be used by console commands, Web service etc.
It is in model where you will have ur business logic defined, independent of the view.
Controller can be thought of as glue that binds Model and View together. They deal directly with client requests and accordingly interact with views and models.
In a well designed application, you data structure and business logic will be designed in a
Model, making it "heavy". While Controller will just interlink your model and view with the client requests, making it "light".
In the classic Model-View-Controller MVC pattern, your Model is essentially a "headless" application, with no UI and is completely UI-agnostics. It offers an API that is the functional core of the application.
The View is the user interface, however you choose to define it (web page? elevator control panel? something else?). A given application might have 1 view or it might have many views.
The Controller (or Controllers — like Views, you might have one to many Controllers for a given application) relays and transforms events, notifications and data between View and Model so as to preclude the Model from needing to know anything that is View-specific.
The idea is to isolate the core application (the Model) from the user interface (the View). From that some things follow:
The View is aware of and communicates with both Controller and Model (you're unlikely to try to wire up the View to another Model) and expected for the Controller to be aware of both View and Model.
The Controller is aware of and communicates with both View and Model.
The Model knows nothing of Controller or View.
Code that performs business logic should be in the Model, not in the Controller.
I'm no MVC expert, but try and concentrate on the fact that the controller should use the input from the user to direct them to the correct view.
I don't know if NerdDinner is an ideal example, but you can see Scott Hanselman et al does a little bit of data access from his EF context but pushes most of the other logic to service classes or helpers on the model.
I don't know if I agree with the 'models heavy' part, as I don't use the models as 'business objects'. If I really need a lot of 'business' logic, I will typically create that in a separate 'Domain' layer and may even have a separate Data Access layer on top of this. But for a lot of simple (see: non-enterprise) projects, this is overkill in my experience.

How should my MVC Model work with my Business logic classes?

So I have a MVC app and in another project I have a normal collection of classes which handle the Business and Data logic for the application. I also have some logic in the Model of the MVC project itself. This logic handles ViewModels and the like, things which could not have been done in the n-tier project as they relate to the MVC project itself and need to be in the same project.
My questions are:
Should my model classes have knowledge of the n-tier business logic? Or should only the controller have this knowledge and send data back and forth between the n-tier application and the MVC model as needed?
If it's ok for my model to reference the n-tier application, then should my controller access n-tier via the model class?
Hope this makes sense, found it difficult to word correctly to get my point across.
Generally speaking here - Your model classes should not have business logic knowledge. They should have only the information required to display the view to the user (use DTOs as suggested by mxmissile).
Your business logic would either be in your controller, or (better) in a separate service layer called by your controller. Having methods on a model that, for instance, bypass the controller and make calls directly to the database is almost always a bad practice.
The idea here is to make the views as dumb as possible. You send them a model, they pull out the data they need, format it appropriately, and display it. This makes it much easier to create new views of the same data later if you decide you want to change the presentation.
Think of your models as only containers for data between your controllers and your views. Essentially DTOs.
Your ViewData/ViewModel classes in your MVC application may contain instances of your Model classes (mine do). My controllers call my business services and are responsible for any translation between ViewData and Models.
If it's ok for my model to reference
the n-tier application, then should my
controller access n-tier via the model
class?
I wouldn't go through the model to get to the application tiers, I would have the controller be that interfacing component. The controller calls to your application tiers which return instances of your Model from your data access components. You can then translate those instances into more consumable objects by using a ViewData/ViewModel object. You can do this in a controller, or use a separate assembler class.

Resources