Nov 01

A friendly “email already taken” error with .NET 11's async validation

.NET 11 lets a validation attribute on a minimal API ask the database whether an email is taken, and answer with a normal 400. That's the friendly message. Two sign-ups at the same moment both pass it, so a unique index is still the guarantee, and its violation should come back as the same 400. Two async checks on one model also run at the same time, so each needs its own DbContext.

dotnet · architecture · 5 min
→
Oct 26

Contain a failing Angular component with @boundary so the rest of the page still works

Angular 22.2 added @boundary, a template block that shows a fallback when a component inside it throws. Without one, a single failing tile can blank a whole dashboard. Wrap each widget, give the fallback a Retry, and keep the ErrorHandler for the clicks and timers the boundary doesn't catch.

angular · architecture · 5 min
→
Oct 14

Live updates from .NET 10 to Angular with Server-Sent Events

.NET 10's ServerSentEvents result streams an IAsyncEnumerable to the browser, and EventSource reads it, reconnects and sends Last-Event-ID with no library. For one-way job progress it's enough, once you've settled how the stream authenticates.

mixed · architecture · 5 min
→
Sep 22

Wire CodeMirror 6 into an Angular form without collapsing the caret

CodeMirror 6 keeps its own copy of the document and changes it through transactions, so wiring it up the way you wire an input either collapses the caret or recurses until the stack ends. The flow that works is one-way, and the line people forget is the one that shuts the view down: an EditorView registers handlers on the document, on the window and on every ancestor element up to html, and Angular removing the component takes back none of them.

angular · architecture · 5 min
→
Sep 20

Angular 22 made OnPush the default, and the migration wrote Eager

Angular 22 made OnPush the default strategy and renamed the old default to Eager, and the update migration writes Eager into the components you already had, so for every component it reaches the upgrade itself changes nothing. What changes is the first component you generate afterwards: it is OnPush, and an Eager component underneath it stops updating for exactly one class of change.

angular · architecture · 6 min
→
Sep 14

Name your HasQueryFilter calls, or the second silently replaces the first

An unnamed HasQueryFilter call sets the filter for an entity type rather than adding to it, so a soft-delete filter written after a tenant filter leaves the tenant condition out of the SQL entirely, with no log line that mentions it. EF Core 10's named filters keep both and let one query drop the soft-delete filter by name while staying inside its own tenant.

dotnet · architecture · 8 min
→
Sep 10

IOptions, IOptionsSnapshot, IOptionsMonitor: which one sees a config reload

IOptions, IOptionsSnapshot and IOptionsMonitor look interchangeable in a constructor and land in three different places when the settings change under a running process. The part worth knowing is what happens when a singleton asks for the scoped one: scope validation is on by default in Development and off everywhere else, so the same code is a startup crash on your machine and a silently frozen value on the server.

dotnet · architecture · 7 min
→
Aug 23

Make a dead BackgroundService show up in your health check

A BackgroundService whose ExecuteAsync returns is finished for the life of the process, and nothing logs it. The stock health endpoint keeps answering 200 Healthy. Two lines of DI and one exception filter fix both halves.

dotnet · architecture · 7 min
→