This question seems to be popping up in several things that I’ve read today. In my personal experience, the answer is: it depends. I’m not sure I could say that there’s any hard-and-fast rule that says where business logic should go, but I will say this, I think the answer lies at least partly in how you define "business logic".

I think there are different kinds of business logic that can be applied at various different levels in an MVC based application. The two primary kinds that come to mind are business process flow logic, and data validation logic. Some might argue that validation logic wouldn’t fall under the category of business logic, but we would have to agree to disagree on that one.

I’ll attempt to explain my position on this with a hypothetical scenario:

Lets say you work in a large medical organization that has development groups that create and maintain multiple different applications that support many different internal parts of the organization. You’re all working with pretty much the same data, but every app uses it a little bit differently, and has different rules that need to be applied to how the data is used and processed. At the same time, all of the applications use the same backend database, so at that level, the rules are the same.

The group you work in has just finished creating a large application that is used by dozens of different departments of the company spread out geographically. As part of the development of your application, you created an assembly that contains all of your model objects, each of which contains its own validation logic to ensure that they don’t allow invalid data to get past them into the backend database.

Now, another group is in the planning stages of an application that will be used by different departments of the company that have their own business process flow, so different business rules will be applied in the application, but since they’re going to be interacting with the same data, rather than reinventing the wheel and creating their own model objects, they’ve decided that they’re just going to reference the assembly that you’ve already created, along with your data access layer for persistence.

Easy stuff, all they need to do is add a reference to your assemblies in their application and they’re off with a model and data access layer already tested and ready-to-go.

In this scenario, both groups are using the MVC design pattern to create their application, but your group has just saved group B a ton of work by providing them with code that they can reuse. Your application has a completely different look and feel at the user interface (View) level, and your business process logic has been implemented in your Controllers. When group B creates their application, they’ve already got the Model and data access layer they need, with data validation built-in. Now all they have to do is create their own Views and Controllers to implement their user interface and business process logic.

See how the business logic actually exists in two different places: in the Controllers for business process logic, and in the Model objects for data validation.

There are most certainly going to be scenarios where all of the business logic for an application is most practically applied at only one level of the app, either the controllers or the model. However, in the interest of developing for security, data validation should be applied at all levels of the application. Why? Considering the above scenario, what might have happened if your group hadn’t added any kind of data validation into the Model objects? When group B started using those objects, if they didn’t add data validation into their Controllers, there exists the potential for invalid data to be allowed into the backend database. Now you’ve got all kinds of potential problems, not just with their application, but potentially yours too. The two applications share a backend. Data security at every level of your application is important, so business logic across multiple layers of your framework can sometimes (often?) be necessary.

UPDATE: An additional consideration that I had forgotten when I wrote this earlier, with regards to adding business logic beyond just data validation to the model objects: A reason to consider NOT putting any more business logic than just data validation into the model objects is that, had that been done by your group, the rules that you had applied could potentially have rendered those model objects useless to group B because the logic that you applied at that level doesn’t apply to their needs. Now, you’ve just lost the advantage of code reuse of those objects, and cost the organization potentially thousands of dollars (maybe tens of thousands, depending on the scope of the project) in time and effort by group B having to re-create their own model objects for their own needs.