The Three Roles: Model, View, Controller
ASP.NET Core MVC divides responsibility into three collaborating pieces: the Model represents application data and business rules (often POCOs, EF Core entities, or dedicated view models); the View, typically a .cshtml Razor file, is responsible purely for rendering HTML from data it is handed; and the Controller, a class deriving from Controller or ControllerBase, receives the incoming request, coordinates with services or repositories to gather or mutate data, and selects which view to render or what result to return. This separation means a change to how data is displayed rarely forces a change to how it's fetched or validated, and vice versa.
Cricket analogy: This is like a cricket broadcast where the on-field umpire (Controller) makes the calls, the statistician (Model) tracks runs and wickets, and the graphics team (View) renders the scoreboard overlay — three separate roles combining into one coherent broadcast without any single person doing all three jobs.
Actions, Routing, and Action Results
A controller's public methods are called actions, and each action typically returns an IActionResult (or a strongly-typed ActionResult<T>) such as View(), RedirectToAction(), Json(), or NotFound(), letting one action decide dynamically what kind of response to produce. Routing to a controller action is configured either via attribute routing, using [Route], [HttpGet], [HttpPost] and similar attributes directly on the action, or via conventional routing registered once in Program.cs with app.MapControllerRoute, which maps URL segments like {controller}/{action}/{id?} to matching class and method names.
Cricket analogy: This is like a bowler at the top of their mark choosing between a yorker, a bouncer, or a slower ball depending on the batter and match situation — the action (delivery) taken varies, similar to an action method returning View(), Json(), or NotFound() based on conditions.
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IOrderService _orderService;
public OrdersController(IOrderService orderService) => _orderService = orderService;
[HttpGet("{id:int}")]
public async Task<ActionResult<OrderDto>> GetById(int id)
{
var order = await _orderService.FindAsync(id);
if (order is null) return NotFound();
return Ok(order);
}
[HttpPost]
public async Task<ActionResult<OrderDto>> Create(CreateOrderRequest request)
{
if (!ModelState.IsValid) return BadRequest(ModelState);
var created = await _orderService.CreateAsync(request);
return CreatedAtAction(nameof(GetById), new { id = created.Id }, created);
}
}View Models and Data Flow
Rather than passing EF Core entities straight to a view, well-structured MVC apps use dedicated view model classes that shape exactly the data a view needs, decoupling the persistence schema from presentation and avoiding accidental over-posting or leaking internal fields to the client. Controllers pass this view model to View(viewModel), and inside the .cshtml file the strongly-typed @model directive gives IntelliSense and compile-time checking against that exact shape, while TempData and ViewData remain available for transient, loosely-typed data like a one-time success message after a redirect.
Cricket analogy: This is like a scorecard summary handed to TV commentators that shows only runs, overs, and wickets — not every internal database field the scoring system tracks — similar to a view model exposing only what the view needs.
Controllers deriving from ControllerBase (used with [ApiController]) omit view-rendering helpers like View() since they're meant for APIs returning JSON, while controllers deriving from Controller include both API-style results and view-rendering support for traditional server-rendered HTML pages.
Avoid binding request input directly to your EF Core entity classes in action parameters for state-changing endpoints — an attacker could set unexpected properties (over-posting) that happen to exist on the entity. Use a dedicated request/DTO class per action and map explicitly to the entity instead.
- MVC separates concerns: Model (data/business rules), View (presentation), Controller (request coordination).
- Actions are public controller methods that return IActionResult or ActionResult<T>.
- Routing can be attribute-based ([Route], [HttpGet]) or conventional via app.MapControllerRoute.
- ControllerBase suits APIs; Controller adds view-rendering support for HTML pages.
- Dedicated view models decouple presentation shape from persistence entities.
- TempData and ViewData carry transient, loosely-typed data such as post-redirect success messages.
- Use request DTOs rather than binding directly to entities to avoid over-posting vulnerabilities.
Practice what you learned
1. In ASP.NET Core MVC, which component is responsible purely for rendering HTML from data it is handed?
2. What is the return type commonly used by controller actions to allow dynamic response selection?
3. Which base class is typically used for API-only controllers that don't render views?
4. Why use a dedicated view model instead of passing an EF Core entity directly to a view?
5. What risk does binding request input directly to an EF Core entity in an action parameter introduce?
Was this page helpful?
You May Also Like
Razor Pages Fundamentals
Learn the page-based programming model in ASP.NET Core where markup and code-behind logic live together, simplifying page-focused scenarios without a separate controller layer.
Tag Helpers and Partial Views
Learn how tag helpers let server-side logic participate in HTML-like markup, and how partial views let you extract and reuse chunks of Razor UI across pages.
Blazor vs MVC vs Razor Pages
Compare ASP.NET Core's three UI programming models — Blazor, MVC, and Razor Pages — to understand their rendering models, state handling, and when each is the right choice.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics