Posts

Current writing from Egil Hansen on .NET, cloud architecture, and software development.

  1. Evolving your C# types without migrating stored JSON

    Data models evolve, but the JSON payloads serialized from the old shapes do not go away. They sit at rest in databases, document stores, caches, queues, and on disk, and they keep arriving over the wire from APIs, Event Hubs, and other systems that have not upgraded yet. The moment I rename a property or restructure a type, deserialization of all that existing JSON breaks. My previous approach was to keep the old C types around and map manually after deserialization: deserialize as UserV1, then convert to UserV2 somewhere downstream. It works, but the migration plumbing leaks into business logic and repository code, and every read path needs to know which historical shapes might show up.

  2. Treat warnings as errors in Debug mode when an AI agent is detected

    Treating warnings as errors is good practice for both humans and AI agents — it keeps the codebase honest. Pair it with an opinionated .editorconfig and analyzers like StyleCop, SonarCloud, or Meziantou, and you get consistent code with clear, actionable diagnostics from the compiler and the Roslyn analysis pipeline.

  3. Verify snapshot tests and AI agents: disable the diff tool

    I use Verify for snapshot testing in .NET projects. It is great, but there is one annoying edge case when an AI agent runs the test suite: a snapshot mismatch can make Verify ask DiffEngine to open my configured diff tool and wait for it to close.

  4. Blazor Server: Stream large amount of data to JavaScript with cancellation

    In a recent Blazor Server (.NET 8) project I needed to send a large amount of data to Plotly.js (+ 50 MB of data). Blazor already have support for streaming data from .NET to JavaScript, however, I wanted to also add support for compression of the data that is sent and cancellation of an ongoing stream of data, in case the user changes their mind and wants to view a different set of data, before the current set of data has been sent.