Entwickler-Blog · Notizen aus der Praxis

Geek Overflow

Notizen aus .NET, WPF, Azure und dem echten Entwickleralltag.

Aktuelle Beiträge
Ein sichtbar genutzter Entwicklerarbeitsplatz mit Tastatur, Notizbuch und Monitor

Aus dem Archiv

Notizen, die im Alltag weiterhelfen.

239 Beiträge

Native OpenTelemetry-Tags in ASP.NET Core

Das Grafana-Dashboard zeigte mir die Anfragedauer sauber nach Route und Statuscode aufgeschlüsselt, aus dem eingebauten Metrik http.server.request.duration. Was fehlte, war unsere eigene Dimension. Ich wollte dieselbe Kurve nach Mandant getrennt sehen, ohne dafür einen zweiten Counter zu bauen, der am Ende nur die Hälfte der Anfragen erwischt. Genau dafür gibt es seit .NET 8 eine Stelle, an der man sich in das schon vorhandene Metrik einklinkt.

Ein .env-File in .NET laden

Ein Kollege schickt mir ein kleines Node-Werkzeug, das ich kurz laufen lassen soll. Im Repository liegt eine .env.example, ich kopiere sie nach .env, trage zwei Werte ein, fertig. Diesen Ablauf haben Leute aus der JavaScript- und Python-Welt im Kopf, und wenn sie dann an einem .NET-Dienst mitarbeiten, suchen sie als Erstes die .env. In .NET gibt es sie von Haus aus nicht. Die Konfiguration kommt aus appsettings.json, Umgebungsvariablen und den User Secrets, nicht aus einer Datei mit Zeilen der Form SCHLUESSEL=WERT.

Runtime-native async in .NET 11

Wenn eine Aufgabe irgendwo in einer Kette von await-Aufrufen festhängt und ich in den Debugger schaue, sehe ich seit Jahren dasselbe: nicht meine Methoden, sondern MoveNext und AsyncMethodBuilderCore.Start in dreizehnfacher Ausführung. Man lernt, das zu überlesen. Schön ist es nicht.

MCP-Server-Vorlage in .NET 11

Bisher fing ein MCP-Server in .NET so an: erst dotnet new install Microsoft.McpServer.ProjectTemplates, dann ein passendes SDK, dann dotnet new mcpserver. Seit .NET 11 fällt der erste Schritt weg, die Vorlage liegt im SDK. Ein dotnet new mcpserver -o MeinServer erzeugt eine Program.cs mit der Transportwahl (stdio oder http), eine Beispielklasse mit einer [McpServerTool]-Methode und eine server.json fürs Veröffentlichen auf NuGet. Native AOT und self-contained lassen sich beim Anlegen gleich mitwählen.

Statisches SSR in Blazor mit Formular, Flash-Message und Cache

Ein internes Werkzeug, alles unter statischem SSR, kein Interaktivitätsmodus. Eine Seite listet Datensätze, eine andere legt einen an. Nach dem Speichern soll “Gespeichert” erscheinen, aber nicht noch einmal, wenn jemand F5 drückt. Und die Listenseite soll nicht bei jedem Aufruf die Datenbank anfassen. Drei Dinge, die einzeln trivial sind und sich zu dritt gegenseitig stören.

DefaultAzureCredential lokal statt Verbindungszeichenfolgen

Eine Verbindungszeichenfolge mit Kontoschlüssel im Klartext ist die bequemste und die unangenehmste Art, lokal an einen Azure-Dienst zu kommen. Bequem, weil sie sofort funktioniert. Unangenehm, weil sie irgendwann in einer appsettings-Datei landet, dann versehentlich im Repository, und weil ihr nie ansieht, wer sie schon einmal kopiert hat. Zugangsdaten aus dem Repository herauszuhalten hatte ich schon einmal mit User Secrets beschrieben. Der Schlüssel selbst bleibt dabei aber ein Schlüssel. Angenehmer ist, lokal gar keinen zu haben.

Collection-Expression-Argumente in C# 15

Seit Collection Expressions schreibe ich Listen und Sets fast nur noch mit eckigen Klammern. Eine Ecke blieb aber hartnaeckig: Sobald ein HashSet<string> gross- und kleinschreibungsunabhaengig vergleichen sollte oder ein Dictionary einen bestimmten StringComparer brauchte, half die kurze Form nicht. Der Comparer wandert in den Konstruktor, und einen Konstruktoraufruf kennt die eckige Klammer nicht. Also zurueck zu new und Objektinitialisierer, und der schoene Spread war weg.

Resilienz-Pipelines mit Microsoft.Extensions.Resilience

Ein interner Dienst antwortete bei uns sporadisch mit 503, meist unter Last, meist nach wenigen Sekunden wieder weg. Der klassische Reflex ist eine Retry-Schleife von Hand, ein bisschen Task.Delay, ein Zaehler. Das funktioniert, bis jemand fragt, warum bei einem Timeout nicht auch abgebrochen wird, und warum der kaputte Dienst weiter mit Anfragen bombardiert wird, obwohl klar ist, dass er gerade nichts liefert. Genau diese Kombination nimmt einem Microsoft.Extensions.Resilience ab, aufgesetzt auf Polly.

LINQ Full Outer Join in .NET 11

Zwei Listen, die sich nur in der Mitte überschneiden: Kunden mit Bestellungen, Bestellungen ohne Kunden, Kunden ohne Bestellung. Ich will alle drei Gruppen in einem Durchgang. In SQL ist das ein FULL OUTER JOIN, in LINQ gab es dafür lange nichts Eingebautes, nur die Krücke aus GroupJoin und DefaultIfEmpty.

Whisper lokal für Transkription

Ich habe eine Handvoll Sprachnotizen und ein paar mitgeschnittene Besprechungen, aus denen ich Text bräuchte. Die bequemen Wege führen alle über einen Dienst, bei dem am Ende meine Aufnahme auf einem fremden Server liegt. Das wollte ich für ein paar interne Mitschnitte nicht, also habe ich mir angesehen, was lokal geht. Whisper von OpenAI läuft auf der eigenen Maschine, und für .NET gibt es mit Whisper.net eine Anbindung an das C++-Original whisper.cpp.

Notizbuch und Tastatur auf einem genutzten Entwicklerarbeitsplatz
Real work / no lab setup

Wer hier schreibt

Matt. Entwickler, Notizsammler, Problemlöser.

Ich schreibe über .NET, C#, WPF, Azure, Werkzeuge – und immer öfter über KI. Nicht aus dem Lehrbuch, sondern aus dem echten Entwickleralltag.

Mehr über mich

Nach Thema einsteigen

Woran ich gerade denke und arbeite.