DEV Community

kirandeepjassal-crypto
kirandeepjassal-crypto

Posted on Originally published at prepstack.co.in

ASP.NET Core Interview Questions for Senior Developers in 2026 — Middleware Pipeline, DI Lifetimes, Kestrel & Auth (Deep Answers)

Junior ASP.NET Core interviews ask "what is middleware." Senior interviews ask why your UseAuthorization ran before routing and silently allowed an anonymous request through, or why a singleton that took a DbContext corrupted data across tenants. The framework is easy to use and easy to misuse in ways that only show up in production — under load, across tenants, at 3am.

This is 30 questions across the four parts that actually separate seniors: the request pipeline, DI & lifetimes, hosting & performance, and auth & APIs. Every answer is a short answer you could say in one breath, a deep dive into the mechanism with code, and the senior signal the interviewer is listening for. Every sample is from Mattrx — a multi-tenant marketing-analytics SaaS on .NET 9 / ASP.NET Core, ~3,200 req/sec peak, Azure SQL + Redis, OAuth via Entra ID.

The lens for all 30

A junior describes a feature; a senior explains the ordering, lifetime, and failure mode. "What is middleware?" gets "a request delegate chain" from a junior and "an ordered, unwinding pipeline where auth must sit between routing and endpoints, and a mis-order silently lets requests through" from a senior.

Block A highlight — the pipeline, and the #1 ordering bug

Middleware is a chain of components, each of which can act on the request, call next(), and act on the response as the chain unwinds. Order is everything: a component only sees what the components before it let through.

Request
  → [ ExceptionHandler ] → [ HTTPS ] → [ Routing ] → [ AuthN ] → [ AuthZ ] → [ Endpoint ]
  ← ───────────────────── response unwinds back up ───────────────────────── ┘
Enter fullscreen mode Exit fullscreen mode

The single most common pipeline bug: UseAuthentication/UseAuthorization must sit between UseRouting and the endpoints. Authorization needs to know which endpoint matched to read its [Authorize] metadata — which only exists after routing — and it must run before the endpoint executes.

app.UseRouting();          // endpoint selected + its [Authorize] metadata attached
app.UseAuthentication();   // populate ctx.User
app.UseAuthorization();    // enforce the selected endpoint's policy
app.MapControllers();      // BUG if this ran before UseAuthorization
Enter fullscreen mode Exit fullscreen mode

Block B highlight — the captive dependency bug

A longer-lived service capturing a shorter-lived one — classically a singleton holding a scoped service. The scoped service now lives forever, leaking state across requests/tenants and breaking thread-safety.

// BUG: singleton CacheWarmer captures a scoped DbContext -> lives for the whole app.
builder.Services.AddSingleton<CacheWarmer>(); // ctor takes MattrxDbContext (scoped)

// FIX: create a scope per unit of work.
public sealed class CacheWarmer(IServiceScopeFactory scopes)
{
    public async Task WarmAsync(CancellationToken ct)
    {
        using var scope = scopes.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<MattrxDbContext>();
        // ...use db within this scope...
    }
}
Enter fullscreen mode Exit fullscreen mode

And why DbContext is scoped: it's not thread-safe and tracks entity state per unit of work. A singleton DbContext across concurrent requests corrupts its change tracker ("A second operation was started on this context") and leaks data across tenants. The same scope-per-unit-of-work rule is how you use a DbContext inside a BackgroundService (which is itself a singleton).

Block C highlight — sync-over-async and thread-pool starvation

Blocking a thread-pool thread (.Result/.Wait()) on async I/O ties up threads that can't serve other requests; under load the pool can't grow fast enough and latency explodes.

// STARVATION: blocks a pool thread on I/O.
var kpis = _service.GetKpisAsync(t, c, r, ct).Result;
// CORRECT: keep the thread free.
var kpis = await _service.GetKpisAsync(t, c, r, ct);
Enter fullscreen mode Exit fullscreen mode

Plus: Kestrel behind a reverse proxy + UseForwardedHeaders, config precedence with secrets in Key Vault, graceful BackgroundService shutdown honoring the stopping token, caching tiers (in-process vs distributed Redis vs output caching), liveness vs readiness health checks, and the built-in rate limiter partitioned per tenant.

Block D highlight — multi-tenant isolation and JWT validation

Derive the tenant from the authenticated token, never from a query string, route, or header the client controls — then scope every query by it (with row-level security as a backstop).

// SAFE: tenant from the verified token, not from input.
var tenantId = User.FindFirstValue("tenant_id")!;      // trusted
var data = await _db.Campaigns.Where(c => c.TenantId == tenantId).ToListAsync(ct);
// NEVER: var tenantId = Request.Query["tenantId"];    // client-controlled -> cross-tenant read
Enter fullscreen mode Exit fullscreen mode

A JWT bearer token is validated every request, statelessly: signature (against the issuer's JWKS), issuer, audience, expiry. The audience check is what stops a token minted for another API being replayed against yours (the confused-deputy guard). Also covered: roles vs claims vs policies vs resource-based auth, the CORS AllowAnyOrigin+credentials mistake, when CSRF actually matters (cookie auth vs bearer tokens), and middleware vs MediatR pipeline behaviors for cross-cutting concerns.

The through-line

Senior ASP.NET Core is four instincts: the pipeline is ordered and it unwinds; lifetimes are about shared state and thread-safety; the tenant and the user come from the token, never the request; and cross-cutting concerns live at the right layer. Answer every question with the mechanism, the real failure it prevents, and the trade-off.

The full guide has all 30 — each with the short answer, the deep dive with code, and the exact senior signal:

https://prepstack.co.in/blog/aspnet-core-senior-interview-questions-middleware-di-kestrel-auth-deep-answers

Originally published on PrepStack.

Top comments (0)