Browse narratives

EN · · 3 min read

What Happens After an HTTP Request Reaches ASP.NET Core

A request-lifecycle model connecting the server, middleware order, endpoint execution, cancellation, and the response path.

Deep DiveIntermediateTime Bound

An ASP.NET Core endpoint can look like a direct function call: accept input, invoke a handler, return a result. The runtime path is a composed pipeline with ordering, short-circuiting, cancellation, and response constraints. Those details become visible when authentication fails, middleware runs in the wrong order, or an exception occurs after the response has started.

The host assembles the boundary

At startup, the application configures services, logging, configuration, the HTTP server, middleware, and endpoints. The result is a request delegate built from middleware registrations. Each middleware can run before the next delegate, call it, run after it returns, or stop the pipeline.

sequenceDiagram participant Client participant Server participant Middleware participant Endpoint Client->>Server: HTTP request Server->>Middleware: HttpContext Middleware->>Endpoint: invoke next Endpoint-->>Middleware: response work completes Middleware-->>Server: unwind in reverse order Server-->>Client: HTTP response

The response path unwinds through middleware in reverse order. This is why exception handling, timing, and response transformation depend on placement.

Order is behavior

Middleware is not a bag of independent filters. Routing must establish endpoint information before components that depend on it. Authentication establishes the principal before authorization evaluates access. Exception handling must wrap the work whose failures it intends to observe.

A terminal middleware or matched endpoint can short-circuit later work. That can improve performance and is also a source of surprising omissions when ordering is accidental.

HttpContext is request-scoped state

HttpContext carries the request, response, user, connection data, features, and request services. It is convenient and belongs to the transport boundary. Passing it deep into domain logic couples rules to hosting concerns and makes lifetimes less clear.

Extract the input and identity facts the use case needs. Return an application result that the endpoint can map to HTTP. This keeps transport-specific behavior at the edge without pretending the transport is irrelevant.

Binding is not validation of meaning

Model binding or parameter binding turns request data into .NET values. It can identify malformed shapes and missing values. Business validity remains a separate concern: whether a transition is allowed, whether the actor has authority, and whether current state satisfies an invariant.

Keeping these failures distinct produces clearer status mapping and telemetry.

Cancellation begins at the connection boundary

HttpContext.RequestAborted signals that request processing should stop, such as when the client disconnects. Propagate the token through application and I/O boundaries where cancellation is safe. Cancellation is cooperative; code that ignores the token continues running.

Do not turn every cancellation into an error log. Distinguish client disconnection, application timeout, host shutdown, and dependency failure when the available evidence supports that distinction.

The response eventually becomes immutable

Once response headers have started, changing the status code or headers may be impossible. Middleware that calls the next delegate and then attempts to replace an already-started response is too late. Streaming makes this boundary especially important because bytes may be committed long before endpoint work finishes.

Observe the lifecycle at boundaries

A useful request trace records route identity, result category, duration, dependency spans, and correlation — not arbitrary payload data. Middleware can measure the whole request, while application instrumentation explains the use case and persistence work inside it.

The endpoint is only one part of the lifecycle. The durable mental model is a pipeline that enters in registration order, may stop early, executes a selected endpoint, and unwinds toward a response whose mutability decreases as it is sent.

Further reading