The MVC Request Pipeline
Every debugging session in an MVC app is easier if you can answer one question: where in the pipeline am I? A request flows through the same stations every time β routing β controller β action β result β view β and each station is a place behavior can be added or broken.
The five stations
- Routing β endpoint routing matches the URL to a controller and action, configured in
Program.cs: a conventional pattern (app.MapControllerRoute(...)with{controller}/{action}/{id?}) plus attribute routing ([Route("orders/{id:int}")]) where URLs need to be explicit. Symptom of a routing problem: 404 with your breakpoint never hit. - Controller creation β the framework asks the DI container to build the controller, which builds its dependencies, which build theirs. Symptom of a DI problem: exception before your action runs ("unable to resolve service...").
- Model binding + action execution β request data becomes typed parameters, filters run, your code runs (next lesson).
- Action result β your action returns a description of the response (
ViewResult,JsonResult,RedirectResult), not the response itself. - Result execution / view rendering β the result executes; a
ViewResultfinds the.cshtml, runs Razor, and writes HTML. Symptom of a view problem: your action succeeded but the page throws β the stack trace points at the view, not the controller.
What surrounds MVC: the middleware pipeline
MVC never sees the raw request first. Requests pass through the middleware pipeline β an
explicit, ordered list in Program.cs:
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(...);
The mental model: cross-cutting concerns that apply to every request (auth, static files, error
pages, logging) live outside MVC as middleware; concerns specific to controllers and actions live
inside as filters. Because the pipeline is just code, order matters visibly β
UseAuthentication before UseAuthorization, or logins silently fail; UseStaticFiles early, so
CSS requests never pay for the rest of the pipeline. When behavior seems to happen "before your
app," read Program.cs top to bottom β that is the pipeline. Legacy note: old System.Web apps
did the same job with HTTP modules buried in web.config, which is why they felt more magical.
Why this map pays rent
When a public-sector app misbehaves, the pipeline tells you where to look: a redirect loop is
middleware or an authorization filter; "my parameter is always null" is model binding;
"the JSON has wrong casing" is result execution; a NullReferenceException with .cshtml in the
stack is the view. Practice narrating a request through the five stations for your own app β it
turns framework mystery into a checklist.