Where can I put custom classes in ASP.NET MVC?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In ASP.NET MVC, custom classes can technically live anywhere in the project as long as the namespace is correct and the file is compiled. The better question is not "where are you allowed to put them" but "where should they go so the project stays understandable."
A good MVC project organizes classes by responsibility, not by convenience. If everything lands in Models or Helpers, the application compiles, but the architecture slowly turns opaque.
Use folders that match responsibility
The classic MVC folders are only the starting point. Controllers belong in Controllers, Razor views belong in Views, and model classes usually belong in Models. Beyond that, you should create folders for the kinds of custom classes your application actually uses.
A common structure looks like this:
This structure is easy to navigate because each folder answers a clear question:
- '
Entitiesor domain models represent business data' - '
ViewModelsshape data for a specific page or form' - '
Serviceshold application logic' - '
Repositoriesisolate persistence concerns' - '
Infrastructurecontains cross-cutting concerns such as caching or email' - '
Filtershold MVC action filters and authorization attributes'
ASP.NET MVC does not require these folder names, but conventions like this reduce friction for the next developer.
Keep view models and domain models separate
One of the most common mistakes is putting every class into a single Models folder and using the same class for both persistence and view rendering. That quickly creates coupling between the UI and the data layer.
A cleaner setup is to separate view models from domain or entity models:
Then keep service logic somewhere else:
This separation keeps controllers thin and makes the application easier to test.
Put business logic outside controllers
Controllers should coordinate a request, not own all the business rules. If a controller is calculating totals, sending email, querying multiple repositories, and formatting output, that code belongs in services or other supporting classes.
Once the logic is moved out, the controller becomes easier to read and unit-test.
Consider a separate class library for larger projects
For small applications, putting custom classes into the MVC project is fine. For larger systems, a separate class library often makes more sense. Domain models, services, repository interfaces, and shared utilities can live outside the web project so they are reusable and easier to test without the MVC host.
This is especially helpful when:
- multiple web apps share the same business logic
- background jobs use the same services
- you want a cleaner boundary between web concerns and domain concerns
The MVC project then becomes a presentation layer instead of the place where every concern accumulates.
Common Pitfalls
- Using
Modelsas a dumping ground for unrelated classes with very different responsibilities. - Putting business rules directly into controllers because it feels faster in the short term.
- Creating vague folders such as
HelpersorUtilsinstead of naming folders by actual responsibility. - Mixing persistence models and view models until UI concerns leak into the data layer.
- Overengineering a small MVC app into too many projects before the complexity actually justifies it.
Summary
- Custom classes can technically go anywhere in an ASP.NET MVC project, but conventions matter.
- Organize classes by responsibility, not by convenience.
- Separate view models, domain models, services, repositories, and infrastructure concerns.
- Keep business logic out of controllers whenever possible.
- Move shared or complex logic into separate class libraries when the application grows.

