Fat model / thin controller vs. Service layer [closed] - asp.net-mvc

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have been developing enterprise applications for many years using .Net
My apps usually have a domain model containing entities mapping to SQL DB tables.
I use a Repository pattern, Dependency injection and a service layer.
Recently we started working on MVC 3 projects and we had a debate where to put which logic.
I came accross thin Controller / FAT Model architecture and was wondering how the service layer would fit in
Option 1 - Model talks to services
Controller is thin, calls methods on the models. The models "know" how to load themselfs from the DB and talk to repositories or services.
E.g. customerModel has a Load(id) method and loads the customer and some child objects like GetContracts().
Option 2 - Controller talks to services
Controller asks Services to retrieve model objects. The logic of loading / storing etc. Is in the service layer. The model is a pure entity model with data only.
Why would option 1 be a better choice especially when we talk about enterprise applictions my experience tells me to separate concerns, keep models AND Controllers as thin as possible and have specialized services doing the Business logic (imcl. The DB interaction)
Thanks for all advices and references to good resources.

All of this depends on the intention and requirements of your application.
That said, here's my suggestion for "mid scale" (not a local restaurant, and not Twitter/Facebook) web applications.
Lean Domain Modeling
Dry POCO style objects, preferably ignorant to the MVC architecture of your web application to remain as loosely coupled from your particular implementation as possible.perhaps even class library repack-able for use in an external application, say a REST API via a WCF Web Service).
"Model" in MVC most accurately means the model the Controller is aware of and thus the the model intended for the View.
In smaller (often Tutorial) applications the entity models of your "Application/Domain Model Layer" are often the same instantiated objects the controller ships off to a View.
In larger applications developers often employ the tenets of MVVM architecture and begin using separate View Model objects. The controllers often call middle-tier services that work with the unseen entities below. In this scenario, the M in MVC most accurately means the View Model.
Robust Service Layer
This does not mean obese logic, but well-written single purpose services. While coding your business logic in services outside of the model is a bit more "procedural" than it is pure "OOP", it helps a lot with loose coupling, testing, and flexible deployment (ex. n-tier deployment).
In my personal practice, I code services both down at the data layer, which I consider my behavioral modeling of the POCO objects (persistence mechanics, low level validation, etc.), and higher level services (business/workflow function) up closer to the MVC mechanics.
Lean Controllers
I make sure my controller is merely the coach, in that it is neither the play (services) or the player (entity model or view model), but simply decides who plays what position and what play to make. My controllers do two things:
Call services that interact with the entity/domain Models
Prepare a View Model for the appropriate View.
Even authenticated/authorized controller actions are done via injected services/attributes.
EDIT 1:
Keep in mind, that this does not mean your Entity/Domain Model is or must be anemic. ORMs, repositories and factories, validation or state mechanics are welcome. It only means for applications of moderate scale, the Model in MVC represents the model meant for the controller, to hand off to your View.
Hopefully this point will calm Fowler apostles who believe the anemic data model to be an anti-pattern. At the same time, it does reflect a slightly more procedural angle than OOP where it is more pure to include behavior in the modeled classes.
There is no "ultimate truth", but using this pattern you'll find it easy to build, test, and deploy your applications - while maintaining a lot of re-usability and scalability.
EDIT 2:
That said, even for modestly sized applications, over architecting (that a word nerds made up?) a system is much too common. For instance, wrapping an ORM with a repository pattern, and then writing services to use the repository... all this is good for separation of concern and such, but if your project doesn't require (and is not very likely to soon require) such things, don't build it. There is nothing wrong with skipping the repository all together, writing thin business services (ex. query classes) against an ORM, or even having your controller talk directly to it. It all depends on scale.
EDIT 3:
I wanted to note that this explanation and advice is for the context of server-side MVC architecture like ASP.Net, not for clent-side frameworks like Knockout or Backbone.

You need to know some more about MVC before we go ahead and discuss where to put everything. Well, if you want to follow the pattern. Otherwise you can stop reading now.
The pattern is very loosely defined. There is nothing that says how the controller, view or model should look like or how they should be structured. The pattern simply states that you should separate the parts and how they should interact with each other. So let's look at bit more about what they are (my interpretation).
MVC
Model
The model can be anything. It can be a webservice, your repositories, your service classes or simply your domain models. The Model are everything that are used to get the information that you need. Consider the "Model" as a layer instead of just an single object.
Controller
The controller is a glue. It takes the information from the Model and adapts it to the view and vice versa.
View
The view should only render what the user sees.
Do note that you should not confuse the Model with View Models. Microsoft should really have named the "Model" folder "ViewModels" since that's what they are. I would not use information from the "Model" directly in the views. Failure to do so would mean that you have to change the Model if the View is changed and the other way around.
The answer
The model is not a view model but a layer. Everything in the model is used to fetch the information needed for the view. The controller takes that information and puts it into a single view model.
A single controller action might use one or several calls to the "Model" to be able to assemble the information needed by the view.
That means that your second option is the most correct when if you want to get an application which is easy to maintain and extend.
Do note that a service layer might not be needed. You can call the OR/M directly from the controllers. But if you find yourself duplicating code or getting fat controllers, simply move the logic to a service layer. Nothing but the controller will be affected by that change since you are using proper view models.

Option 1:
You could think that model == service.
Model also IS the business layer.
Option 2 is an Anemic Domain Model anti-pattern.
http://en.wikipedia.org/wiki/Anemic_domain_model

Option 2 is what's described as Fat Stupid Ugly Controllers architecture (Reference to author of this expression). This solution is generally against MVC spirit as it breaks separation of concerns.

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.

ASP.NET MVC vs. nTier Separation of Concerns

with nTier architecture it is common to create a data, business, workflow and ui layer. In this setup, your data layer and business layers are separated and can be reused by other layers.
In ASP.NET MVC it seems that the model is acting as both the business and data layer as clearly the model is the data and all documentation indicates that business logic belongs in the model.
How is this architecture promoting good separation of concerns when these two layers are mixed?
There is a difference between View Models and Domain Models. Domain Models is your application domain. These models can be used everywhere, in any tier and they are usually placed in a separate shared project. Your View Models are just for the UI. They are dependent on your page needs/structure. Let's say you want to create user management page, than your view model may be a class with 2 properties User and List<Role> where User and Role are domain models.
And finally, your Data Models usually are just database transfer objects. Entity Framework models are usually used as Data and Domain models at the same time.
So, answering your question: you choose your comfortable level of mixing models by yourself. The problem is if you don't want to mix, then you will have quite a bit of model duplications across the solution and you will have to do mapping from one type of model to the other manually or with help of libraries like AutoMapper. That's why developers choose some compromise.
Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user. (Wikipedia)
We should take into account that when we talk about ASP.NET MVC, we are talking about "User Interface" so, it is a user interface framework not an application one. In MVC, concerns are separated in three components: Model, View and Controller.
In multi-layer or multi-tier architecture, concerns are mostly separated in Presentation, Application, Business and Data access layers which is an application framework architecture and ASP.NET MVC belongs to the Presentation layer.
All in all, separation of concern is completely achieved if we distinguish between Application and Presentation frameworks.
Andrei M is spot on. I agree with the difference between View models and domain models. It may help to think of the M in MVC as a model for your views, and these "view models" should not have any knowledge of where they get their data from. Therein lies the separation of concerns. A controller will broker the exchanges necessary between your domain model and your view models to populate the view models with data. These data exchanges that the controller brokers are often achieved by using another layer such as a repository, infrastructure, or service layer... but not necessarily. In a one-project solution, your "Models" folder might contain a domain model, and then you might have a separate folder called "ViewModels". A controller would fetch data via "the Model" and then populate the view model with the data it "received" from the model. The view model would be the underlying model for your strongly-typed view. One may wonder why a developer might even bother with using a view model if there is a simple one-to-one mapping between domain object and a view. One example is that you may need to "flatten" a domain object and its relationships. Another example might be that for an index or list page, you may need to include search filter; view models greatly simplify accommodating changes to requirements.

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.

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.

Where does the "business logic layer" fit in to an MVC application?

First, before anyone screams dupe, I had a hard time summarizing it in a simple title. Another title might have been "What is the difference between a domain model and MVC model?" or "What is a model?"
Conceptually, I understand a Model to be the data used by the views and controller. Beyond that, there seems to be a great deal of differing opinions on what makes up the model. What's a domain model, versus an app model, vs a view model, vs a service model, etc..
For example, in a recent question I asked about the repository pattern, I was told point blank that the repository is part of the model. However, I have read other opinions that the model should be seperated from the persistence model and the business logic layer. After all, isn't the Repository pattern supposed to decouple the concrete persistence method from the model? Other people say there is a difference between the Domain model and the MVC model.
Let's take a simple example. The AccountController that is included with the MVC default project. I've read several opinions that the Account code included is of poor design, violates SRP, etc.. etc.. If one were to design a "proper" Membership model for an MVC application, what would that be?
How would you seperate the ASP.NET services (Membership provider, role provider, etc..) from the model? Or would you at all?
The way I see it, the model should be "pure", perhaps with validation logic.. but should be seperate from business rules (other than validation). For example, let's say you have a business rule that says someone must be emailed when a new account is created. That doesn't really belong in the model in my view. So where does it belong?
Anyone care to shed any light on this issue?
The way I have done it - and I'm not saying it is right or wrong, is to have my View and then a model that applies to my view. This model only has what is relevant to my view - including data annotations and validation rules. The controller only houses logic for building the model. I have a service layer which houses all business logic. My controllers call my service layer. Beyond that is my repository layer.
My domain objects are housed separately (in their own project, actually). They have their own data annotations and validation rules. My repository validates the objects in my domain before saving them into the database. Because every object in my domain inherits from a base class which has validation built in, my repository is generic and validates everything (and requires it inherits from the base class).
You might think that having two sets of models is duplication of code, and it is to an extent. But, there are perfectly reasonable instances where the domain object is not appropriate for the view.
Case in point is when working with credit cards - I have to require a cvv when processing a payment, but I cannot store the cvv (it is a $50,000 fine to do so). But, I also want you to be able to edit your credit card - change of address, name, or expiration date. But you aren't going to give me the number or the cvv when editing it, and I certainly am not going to put your credit card number in plain text on the page. My domain has these values required for saving a new credit card because you give them to me, but my edit model doesn't even include the card number or cvv.
Another benefit to so many layers is that if architected correctly, you can use structuremap or another IoC container and swap out pieces without detrimentally affecting your application.
In my opinion, controller code should only be code targeted at the view. Show this, hide that, etc. The service layer should house the business logic for your app. I like having all of it in one place so it's easy to change or tweak a business rule. The repository layer should be relatively dumb - devoid of business logic and only query your data and return your domain objects. By separating the view models from the domain model, you have much more flexibility when it comes to custom validation rules. It also means you don't have to dump every piece of data into your view in hidden fields and push it back and forth between the client and server (or rebuild it on the backend). Your view model will then house only the information relevant to the view - and it can be customized to have bools for view logic or counts or enums so that the view itself isn't cluttered up with complicated logic statements like
<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) &&
Model.SomeObject.SomeInt == 3 && ...) { %>
While everything seems spread out and over-layered, it has a purpose for being architected this way. Is it perfect? not really. But I do prefer it to some past designs of calling repositories from the controller and having business logic mixed in the controller, repository, and model.
I too often wondered how exactly the MVC elements fit in a traditional web application structure, where you have views (pages), controllers, services, and data objects (model). As you said, there are many versions of that.
I believe the confusion exists because of the above stated, widely accepted architecture, which uses the "anemic domain model" (alleged)-anti pattern. I won't go into much details about the "anti-patternness" of anemic data model (you can look at an effort of mine to explain things here (Java-based, but relevant for any language)). But in short, it means that our model holds only data, and business logic is placed in services/managers.
But let's assume we have domain driven architecture, and our domain objects are the way they are expected to be - having both state and business logic. And in this domain-driven perspective things come into place:
the view is the UI
the controller gathers the inputs of the UI, invokes methods on the model, and sends back a response to the UI
the model is our business components - holding the data, but also having business logic.
I guess that answers your main questions. Things get complicated when we add some more layers, like the repository layer. It is often suggested that it should be invoked by the business logic placed in the model (and hence each domain object has a reference to a repository). In the article of mine that I linked I argue that this is not quite a best practice. And that in fact it is not a bad thing to have a service layer. By the way, domain-driven design does not exclude the service layer, but it is supposed to be 'thin', and only coordinating domain objects (so no business logic there).
For the anemic data model paradigm, which is widely adopted (for good or for bad), the model would be both the service layer and your data objects.
In my opinion,
Model -
Should not contain business logic, it should be pluggable(WCF like scenario). It is used to bind to view so, it should have properties.
Business Logic -
It should be placed at "Domain Services Layer", it is separate layer altogether.
Also, will add one more layer here "Application Services".
App Services talks to Domain Services layer to apply business logic and then lastly return the Model.
So,
Controller will ask Application Service for Model and the flow will go like,
Controller->Application Services(using domain services)->Model
The MVC pattern and the Asp.net framework makes no distinction on what the Model should be.
MS's own examples include persistence classes in the model. Your question about membership being in the model. This depends. Are classes in your model owned by something? Is there a link between who logs in and what data is displayed? Is there filtering of data part of a permissions system that is editable? Is who last updated or edited an object part of your domain as in somebody else needs to see it or something for backend support?
The email example is also it depends. Are you familiar with domain eventing or eventing in particular? Do you have a separate service to send emails? Is the act of sending an email part of your domain or is it a application level concern outside of the scope of your system? Does the UI need to know if an email was sent successfully or not? Do emails that fail to send need retries? Does the content of the email sent need to be stored for support or customer service requirements?
These types of questions are overly broad and subjective but I'm answering so you and everybody who voted you up can understand this.
Your requirements/timelines/resources all bleed into your system's architecture. Even the revenue model can have an effect. You also have to consider the pattern you are shooting for. DDD is much different than persistence-as-model applications and all the slop in between are also valid for certain apps. Are you shooting for testing the app? All of this has an effect.

Resources