Don’t let scrapers crash your API. Since .NET 7, you can implement rate limiting natively. builder.Services.AddRateLimiter(options => { options.AddFixedWindowLimiter(“fixed”, opt => { opt.PermitLimit = 10; opt.Window = TimeSpan.FromSeconds(10); }); });
Category: Asp.Net Core
.NET Core: Master DI Lifecycles (Transient vs Scoped vs Singleton)
Choosing the wrong lifecycle is the #1 cause of bugs in .NET Core APIs. Transient: New every time. Perfect for stateless services. Scoped: Once per request. Ideal for Database Contexts. Singleton: Once for app life. Best for Caching.
.NET Core: Custom Middleware for Global Exception Handling
Stop using try-catch in every controller. Handle errors globally and return consistent JSON. app.UseExceptionHandler(appError => { appError.Run(async context => { context.Response.StatusCode = 500; await context.Response.WriteAsJsonAsync(new { Error = “Internal Server Error” }); }); });
.NET Core: Implement Built-in Health Checks for Microservices
Let your load balancer or K8s know your app is healthy. builder.Services.AddHealthChecks(); app.MapHealthChecks(“/health”);
.NET Core: Use Endpoint Filters for Clean Request/Response Pipeline
Middleware affects all endpoints. Endpoint Filters apply logic only to specific endpoints you choose. Create Filter: public class LoggingFilter : IEndpointFilter { public async ValueTask InvokeAsync( EndpointFilterInvocationContext context, EndpointFilterDelegate next) { Console.WriteLine($”Before: {context.HttpContext.Request.Path}”); var result = await next(context); // Call next filter/endpoint Console.WriteLine($”After: {context.HttpContext.Response.StatusCode}”); return result; } } Apply to Specific Endpoint: app.MapGet(“/api/data”, () => […]
.NET Core: Use BenchmarkDotNet to Accurately Measure Performance
Timing code with DateTime.Now is inaccurate. BenchmarkDotNet runs proper benchmarks with statistical analysis. Install: dotnet add package BenchmarkDotNet Create Benchmark: using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; [MemoryDiagnoser] public class StringBenchmarks { [Benchmark] public string StringConcat() { string result = “”; for (int i = 0; i < 1000; i++) result += i.ToString(); return result; } [Benchmark] public […]
.NET Core: Use Result Pattern to Avoid Exceptions for Expected Errors
Throwing exceptions for business logic (user not found, invalid input) is expensive. Result pattern is cleaner and faster. Define Result Type: public class Result { public T? Value { get; } public string? Error { get; } public bool IsSuccess { get; } private Result(T value) { Value = value; IsSuccess = true; } private […]
.NET Core: Use IOptions Pattern for Strongly-Typed Configuration
Reading config with magic strings breaks on typos. IOptions pattern gives strongly-typed, validated config. Define Config Class: public class EmailSettings { public string SmtpHost { get; set; } = string.Empty; public int SmtpPort { get; set; } public string Username { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; […]
.NET Core: Use Polly for Resilient HTTP Requests with Retry Logic
Network failures happen. Polly adds retry, circuit breaker, and timeout policies automatically. Install: dotnet add package Polly dotnet add package Microsoft.Extensions.Http.Polly Add to HttpClient: // Program.cs builder.Services.AddHttpClient(“MyAPI”, client => { client.BaseAddress = new Uri(“https://api.example.com”); }) .AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt))) ) .AddTransientHttpErrorPolicy(policy => policy.CircuitBreakerAsync(5, TimeSpan.FromMinutes(1)) ); Usage: public class MyService { private readonly […]
.NET Core: Use Dapper for Lightweight ORM Alternative to Entity Framework
Entity Framework too heavy for simple queries? Dapper is micro-ORM with near-raw SQL performance. Install: dotnet add package Dapper Basic Usage: using Dapper; using System.Data.SqlClient; var connection = new SqlConnection(connectionString); // Query (returns list) var users = connection.Query( “SELECT * FROM Users WHERE Age > @MinAge”, new { MinAge = 18 } ).ToList(); // Single […]
.NET Core: Use Rate Limiting to Prevent API Abuse
APIs getting hammered with requests? .NET 7+ has built-in rate limiting middleware. Setup: // Program.cs builder.Services.AddRateLimiter(options => { options.AddFixedWindowLimiter(“fixed”, opt => { opt.Window = TimeSpan.FromMinutes(1); opt.PermitLimit = 100; // 100 requests per minute opt.QueueLimit = 0; }); }); var app = builder.Build(); app.UseRateLimiter(); Apply to Endpoints: app.MapGet(“/api/data”, () => “Data”) .RequireRateLimiting(“fixed”); // If user exceeds […]
.NET Core: Use Health Checks to Monitor Application Status
Need to know if your app is healthy? Health checks provide monitoring endpoints automatically. Setup: // Program.cs builder.Services.AddHealthChecks() .AddDbContextCheck() // Check database .AddUrlGroup(new Uri(“https://api.example.com”), “External API”); // Check external dependency var app = builder.Build(); app.MapHealthChecks(“/health”); Test: curl http://localhost:5000/health # Healthy response: 200 OK # Unhealthy: 503 Service Unavailable Custom Health Check: public class MemoryHealthCheck : […]
.NET Core: Use Output Caching to Cache Entire HTTP Responses
Response caching at application level is slow. Output caching caches at server level for max speed. Enable (.NET 7+): // Program.cs builder.Services.AddOutputCache(); var app = builder.Build(); app.UseOutputCache(); Use on Endpoints: app.MapGet(“/products”, async (IProductService service) => { return await service.GetAllProductsAsync(); }) .CacheOutput(policy => policy.Expire(TimeSpan.FromMinutes(5))); // First request: 50ms (database query) // Next requests: 0.5ms (from cache) […]
.NET Core: Use ILogger with Scopes for Better Log Context
Logs without context are hard to trace. Scopes add contextual information to all logs within a scope. Basic Logging: _logger.LogInformation(“Processing order”); _logger.LogInformation(“Payment completed”); // Hard to know which order in production logs With Scopes: using (_logger.BeginScope(“OrderId:{OrderId}, UserId:{UserId}”, orderId, userId)) { _logger.LogInformation(“Processing order”); _logger.LogInformation(“Payment completed”); _logger.LogInformation(“Email sent”); } // All logs include: OrderId:12345, UserId:67890 // Easy […]
.NET Core: Use BackgroundService for Long-Running Tasks
Need background job in your ASP.NET app? BackgroundService is built-in – no Hangfire or Quartz needed. Create Background Service: public class EmailCleanupService : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // Do work await CleanupOldEmails(); // Wait 1 hour await Task.Delay(TimeSpan.FromHours(1), stoppingToken); } } private async Task CleanupOldEmails() { // […]
.NET Core: Use IConfiguration.GetValue for Type-Safe Config Reading
Parsing config strings manually is error-prone. GetValue handles conversion automatically. Manual Parsing (Error-Prone): // appsettings.json: “MaxRetries”: “3” var maxRetries = int.Parse(_config[“MaxRetries”]); // NullReferenceException if key missing! // FormatException if value is not a number! Type-Safe GetValue: var maxRetries = _config.GetValue(“MaxRetries”, defaultValue: 5); // Returns 3 if exists // Returns 5 if missing or invalid // […]
.NET Core: Use Required Modifier to Force Property Initialization
Tired of null reference exceptions because someone forgot to set a property? Make it required. Old Problem: public class User { public string Name { get; set; } // Can be null! public string Email { get; set; } // Can be null! } var user = new User(); // Compiles fine Console.WriteLine(user.Name.Length); // NullReferenceException! […]
.NET Core: Use Global Using Directives to Avoid Repeating Imports
Typing the same using statements in every file? Declare them globally once. Create GlobalUsings.cs: // GlobalUsings.cs global using System; global using System.Collections.Generic; global using System.Linq; global using System.Threading.Tasks; global using Microsoft.EntityFrameworkCore; Now these namespaces are available in ALL files automatically! Your Other Files: // ProductService.cs // No using statements needed! public class ProductService { private […]
.NET Core: Use File-Scoped Namespaces to Reduce Indentation
Tired of extra indentation from namespace blocks? Use file-scoped namespaces. Old Way: namespace MyApp.Services { public class ProductService { public void DoSomething() { // Code here } } } // Everything indented one level New Way (.NET 6+): namespace MyApp.Services; public class ProductService { public void DoSomething() { // Code here – one less indent […]
.NET Core: Use Top-Level Statements to Skip Program Class Boilerplate
Don’t need Program class and Main method for simple apps. Write code directly. Old Way: namespace MyApp { class Program { static void Main(string[] args) { Console.WriteLine(“Hello World”); } } } New Way (.NET 6+): Console.WriteLine(“Hello World”); That’s your entire Program.cs file! Compiler generates the boilerplate. Can Still Use Services: var builder = WebApplication.CreateBuilder(args); var […]
.NET Core Middleware Magic: How to Build Pipeline Filters That Transform Your API
Need consistent request/response handling across all endpoints? Custom middleware creates reusable pipeline components. Custom Middleware for Global Exception Handling: // GlobalExceptionMiddleware.cs public class GlobalExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; private readonly IWebHostEnvironment _env; public GlobalExceptionMiddleware( RequestDelegate next, ILogger logger, IWebHostEnvironment env) { _next = next; _logger = logger; _env = env; […]
.NET Core Configuration Magic: How IOptions Pattern Solves Multi-Environment Headaches
Tired of connection strings breaking between dev/test/prod? IOptions pattern with validation ensures your app never starts with wrong config. The Configuration Nightmare: // The old way – scattered magic strings public class OrderService { private readonly string _connectionString; public OrderService(IConfiguration configuration) { _connectionString = configuration.GetConnectionString(“DefaultConnection”); // What if configuration key doesn’t exist? // What if […]
.NET Core: Use Minimal APIs to Create Lightweight Endpoints Without Controllers
Creating a controller, action method, and routing just to return simple JSON? Minimal APIs in .NET 6+ let you define endpoints in 3 lines. Traditional Controller Way: [ApiController] [Route(“api/[controller]”)] public class ProductsController : ControllerBase { private readonly IProductService _productService; public ProductsController(IProductService productService) { _productService = productService; } [HttpGet] public async Task GetAll() { var products […]
.NET Core: Use IMemoryCache for Lightning-Fast Data Access Without Redis
Hitting database for same data 1000 times per second? IMemoryCache stores frequently-accessed data in RAM for instant access. Setup: // Program.cs or Startup.cs builder.Services.AddMemoryCache(); Basic Usage: public class ProductService { private readonly IMemoryCache _cache; private readonly ApplicationDbContext _db; public ProductService(IMemoryCache cache, ApplicationDbContext db) { _cache = cache; _db = db; } public async Task GetProductAsync(int […]
.NET Core: Fix Memory Leaks by Understanding IDisposable and Using Patterns
Your .NET application’s memory usage grows infinitely? You’re probably not disposing resources properly. Here’s the complete guide. The Memory Leak – Classic Example: // WRONG: Memory leak public async Task ProcessOrdersAsync() { var dbContext = new ApplicationDbContext(); var orders = await dbContext.Orders.ToListAsync(); // Process orders… // dbContext never disposed = connection stays open = memory […]
.NET Core: Reduce Docker Image Build Time with Layer Caching Optimization
Your .NET Docker builds take 5-10 minutes every time? Improper Dockerfile layer ordering is killing your cache efficiency. Bad Dockerfile (No Cache Optimization): FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src # This invalidates cache on EVERY code change COPY . . RUN dotnet restore RUN dotnet build -c Release RUN dotnet publish -c Release -o /app/publish […]
Why IHttpClientFactory Can Still Exhaust Sockets
Most people think it magically fixes everything. Reality Misusing named clients causes: DNS caching issues Handler lifetime misuse Hidden fix Use typed clients for long-lived services. Why Typed clients scope handlers correctly to the service lifetime.
Why BackgroundServices Die Silently in Production
Looks fine locally.Stops running in prod. Root cause Unhandled exceptions inside ExecuteAsync. What actually happens The host kills the service quietly. Correct pattern protected override async Task ExecuteAsync(CancellationToken ct) { while (!ct.IsCancellationRequested) { try { await DoWork(ct); } catch (Exception ex) { logger.LogError(ex, “Background task failed”); await Task.Delay(5000, ct); } } } Cause → Effect […]
Why Background Services Stop Without Errors
BackgroundService silently dies if an exception escapes. Rule Always wrap execution loops. while (!stoppingToken.IsCancellationRequested) { try { await DoWork(); } catch (Exception ex) { Log(ex); } } Why Unhandled exceptions kill the worker.
Why HttpClient Causes Random Timeouts
Creating HttpClient per request is a silent killer. Problem Socket exhaustion DNS caching issues Fix Use IHttpClientFactory. services.AddHttpClient(); Why It pools handlers safely.
























