Skip to main content

Posts

Showing posts with the label ASP.NET Core

HttpClient in .NET 10: IHttpClientFactory, Timeouts, Retries

Last updated: October 8, 2026 · Tested with .NET 10 (SDK 10.0.401, runtime 10.0.12), Microsoft.Extensions.Http.Resilience 10.10.0 (Polly.Core 8.4.2), Windows 11 Short answer: don't create a new HttpClient() per request. Get clients from IHttpClientFactory ( AddHttpClient , named or typed), or keep one static HttpClient on a long-lived SocketsHttpHandler with PooledConnectionLifetime set so DNS changes are picked up. For retries and timeouts add AddStandardResilienceHandler() from Microsoft.Extensions.Http.Resilience and let it own the timeouts. Below is what I measured against a local Kestrel test server: 2,000 sockets left in TIME_WAIT by the per-request pattern, the exact timeout exceptions, real retry logs, a measured Retry-After delay, and one surprise: the standard handler silently replaces your HttpClient.Timeout . The Test Setup All examples run as console apps against a minimal API on http://127.0.0.1:5199 in the same solution. It has endpoints that answer f...

ASP.NET Core Rate Limiting: 4 Algorithms Compared on .NET 10

Last updated: October 1, 2026 · Tested with .NET 10 (SDK 10.0.201), built-in Microsoft.AspNetCore.RateLimiting , xUnit + Microsoft.AspNetCore.Mvc.Testing 10.0.12 Short answer: ASP.NET Core has rate limiting built in since .NET 7. Register policies with builder.Services.AddRateLimiter(...) , add app.UseRateLimiter() , and attach a policy to an endpoint with .RequireRateLimiting("name") or [EnableRateLimiting("name")] . There are four algorithms: fixed window, sliding window, token bucket and concurrency. I ran all four in a .NET 10 app against a small HTTP client that timestamps every request. The output below is real, and it caught three things most examples get wrong. Rejections are 503 unless you change it. A policy registered with AddFixedWindowLimiter is one counter shared by every client . And the sliding window limiter never sends Retry-After . Minimal Setup No NuGet package is needed; the middleware is part of the shared framework. using System.Th...

Hangfire vs Quartz.NET vs BackgroundService in .NET 10

Last updated: September 27, 2026 · Tested with .NET 10 (SDK 10.0.201), Hangfire 1.8.25, Quartz.NET 4.2.0 Short answer: use BackgroundService for continuous loops such as queue consumers and outbox processors. Use Hangfire for jobs that users trigger and that must not be lost, like emails, PDFs and webhooks, because it gives you persistence, automatic retries and a dashboard. Use Quartz.NET when the schedule itself is complicated: business-hours cron, calendars, misfire rules, or a guarantee that runs never overlap. I built one .NET 10 app that runs all three side by side, and the real console output is below. Every ASP.NET Core app eventually needs work outside the request pipeline: sending emails, generating reports, syncing with a third-party API, cleaning up stale rows at 2 AM. All three options are production-proven, but they solve different problems. Picking the wrong one leads to lost jobs after a deploy, duplicate work when you scale out, or hundreds of lines of hand-wr...

ASP.NET Core Health Checks on .NET 10: Setup and Gotchas

Last updated: October 1, 2026 · Tested with .NET 10 (SDK 10.0.201), AspNetCore.HealthChecks.* 9.0.0, EF Core 10.0.12, SQL Server LocalDB Short answer: call builder.Services.AddHealthChecks() , chain one check per dependency, and expose it with app.MapHealthChecks("/health") . The endpoint returns Healthy with HTTP 200, or Unhealthy with HTTP 503. For real deployments you want two endpoints (liveness without dependencies, readiness with them), a JSON body for humans, and timeouts on every check. I built all of that in one .NET 10 app and hit it with curl. Every response below is real output, and three results surprised me: a 2-second timeout that let a check run for 6 seconds and still report Healthy, Degraded returning 200, and exception messages showing up in the public JSON. The Minimum Setup Health checks are part of ASP.NET Core itself ( Microsoft.Extensions.Diagnostics.HealthChecks is in the shared framework), so the basic version needs no NuGet package: va...

CQRS with MediatR in ASP.NET Core: A Working Example

Last updated: October 1, 2026 · Tested with .NET 10 (SDK 10.0.201), MediatR 12.5.0, FluentValidation 12.1.1, EF Core 10.0.12 Short answer: CQRS splits your application code into commands that change state and queries that only read it. MediatR is the in-process dispatcher that routes each one to exactly one handler, so an endpoint does nothing but sender.Send(request) , and cross-cutting work such as validation and logging is written once as a pipeline behavior. Below is a complete working example on .NET 10 with the real console and HTTP output, what happens when a notification handler throws, what the mediator costs per call, and one thing to know before you install it: MediatR 13 and later are commercially licensed , and that is the version NuGet gives you by default. What CQRS Means Here CQRS stands for Command Query Responsibility Segregation. A command expresses an intent to change something ( CreateProduct , DeactivateCustomer ) and returns little or nothing. A query re...