Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Optimistic Concurrency End to End: From rowversion to ETag, If-Match, 412 and a Conflict UI
Building optimistic concurrency end to end on the web means exposing rowversion as an ETag, requiring If-Match on updates (428 otherwise), returning 412 with the current values on a mismatch and doing a field-level three-way merge on the client. As a follow-up to the EF Core Concurrency post, this post shows the HTTP and Angular side with real output.
Idempotency Keys: Not Creating the Same Order Twice on Double Clicks and Retries
The reliable way to stop the same order from being created twice on double clicks and retries is for the server to store a client-generated Idempotency-Key per user together with a request hash, and to write the work and the 'completed' record in the same transaction. This post covers the current status of the IETF draft (draft-08, not an RFC), the 400/409/422 rules and an ASP.NET Core endpoint filter + SQL Server implementation with real output.
Designing Feature Flags in Code: Toggle Types, Microsoft.FeatureManagement and Flag Debt
Designing a feature flag well means identifying its type first (release, experiment, ops, permission), keeping the decision in a single toggle router and giving every flag an owner and an expiration date. The post shows a tenant filter with Microsoft.FeatureManagement 4.8.0, in-request consistency with snapshots, a kill switch with WithFeatureGate and a test that catches expired flags, with real output.
Provider-Independent LLM Code: IChatClient, the OpenAI-Compatible /v1 and DI
With the IChatClient abstraction we run the same code through Ollama's own API and its OpenAI-compatible /v1 endpoint, switching providers through configuration and environment variables. We wire it into an ASP.NET Core minimal API with DI, keep API keys in user secrets and environment variables, build the same idea in TypeScript with the openai package, and look at the limits of the abstraction.
Async and Connection Management in Dapper: CancellationToken, Pooling and DI
We see with real output why a CancellationToken only travels through CommandDefinition in Dapper, why async on SQLite actually runs synchronously, how connection pooling helps, why sharing one connection breaks, and the connection factory pattern in ASP.NET Core.
EF Core in ASP.NET Core: AddDbContext, Scoped Lifetime, Factory and Pooling
We wire DbContext into ASP.NET Core with AddDbContext, watch the scoped lifetime through ContextId, solve the singleton and background service traps, and see with real output when AddDbContextFactory and AddDbContextPool help.
What's New in .NET 10: AddValidation, OpenAPI 3.1 and Server-Sent Events in ASP.NET Core
.NET 10 LTS brings AddValidation to minimal APIs, OpenAPI 3.1 and YAML, TypedResults.ServerSentEvents, System.Text.Json-based JSON Patch, dotnet run app.cs, C# 14 and breaking changes such as cookie auth 401/403.
What's New in .NET 9: Built-in OpenAPI, Scalar and HybridCache in ASP.NET Core
.NET 9 drops Swashbuckle from the template: AddOpenApi/MapOpenApi, transformers, Scalar and Swagger UI, stampede-safe HybridCache, TypedResults.InternalServerError, StatusCodeSelector, C# 13 and 24-month STS support.
What's New in ASP.NET Core with .NET 8: Keyed DI, IExceptionHandler, Identity API and Native AOT
Keyed DI, IExceptionHandler, MapIdentityApi, ShortCircuit, TimeProvider, Native AOT and the minimal API template in .NET 8, compared with .NET 6, plus C# 12, migration notes and the November 10, 2026 end of support.
What's New in ASP.NET Core with .NET 7: MapGroup, TypedResults, Rate Limiting and Output Caching
MapGroup, TypedResults and Results<T1,T2>, endpoint filters, AddProblemDetails, rate limiting and output caching in .NET 7, compared with .NET 6, plus C# 11 required members, raw string literals and migration notes.
Reading Old .NET Core 3.1 and .NET 5 Projects: Migrating from Startup.cs to .NET 6
We read the Startup.cs, Generic Host and UseRouting/UseEndpoints structure of the .NET Core 3.1 and .NET 5 era, then move the same ASP.NET Core API to .NET 6 step by step, including System.Text.Json differences.
Containerizing an ASP.NET Core Web API with Docker and Setting Up CI/CD with GitHub Actions
We containerize an ASP.NET Core Web API with a multi-stage Dockerfile: dotnet publish, the layer cache, .dockerignore, ports and environment settings; then we build a GitHub Actions CI/CD pipeline that tests the code and pushes the image to ghcr.io.