Posts

Showing posts from November, 2024

Audit Trails in EF Core

Introduction Audit trails is a common feature in database systems. Essentially, it's about knowing, for every table (or some selected ones), who created/updated each record, and when the creates/updates happened. It can also be useful to store the previous values too. Some regulations, such as SOX , require this for compliance. There are some libraries that can do this automatically in EF Core , and there's also the Change Data Capture in SQL Server (and possibly other databases too), of which I wrote about some time ago, but, hey, I wanted to write my own, so here is EFAuditable , my library for doing audit trails in EF Core. This one is designed with some extensibility in mind, so, please, read on. Scenarios EFAuditable  allows the following scenarios: Entities marked for auditing will have the audit columns added and persisted automatically to the database, on the same table Entities marked for history keeping will have their old values (in the case of updates or deletes) ...

Domain Events with .NET - Events Dispatcher Executor

Introduction You may remember my Domain Events with .NET post and library . I recently made some changes , and now, some more, of which I'll talk here. I'm now introducing a new concept: A  dispatcher executor  is a class that is responsible for calling subscribers when invoked by a dispatcher Events Dispatcher Executor Essentially, it's a new interface/abstraction,  IEventsDispatcherExecutor . This interface - or, rather, one implementation of it - is the actual responsible for calling a subscription inside the  IEventsDispatcher  implementation, so all existing implementations were modified to use it. This allows, for example, a retry strategy. I included a simple one, which can be applied by using the WithRetries extension method: builder.Services.AddDomainEventsFromAssembly(typeof(Program).Assembly) .WithRetries(3, TimeSpan.FromSeconds(3)); And this is it. In the case of any exception while invoking the subscription, the executor will retry a number of...

ASP.NET Core Pitfalls – Posting a String

This is another post on my ASP.NET Core pitfalls series . It is actually related to this one  ASP.NET Core Pitfalls – Null Models in Post Requests . What happens if you try to submit a string containing JSON as a POST? I mean, you always submit strings, but this time you don't want for it to be parsed into some class. Like this: [HttpPost] public IActionResult PostString([FromBody] string json) { ... } You may be surprised to find out that this fails with a HTTP 415 Unsupported Media Type . Now, you might be tempted to add an [Consumes] attribute to it, such as: [HttpPost] [Consumes("application/json")] public IActionResult PostString([FromBody] string json) { ... } And this will actually work! The problem is, or could be, that it requires the sender to send the appropriate Content-Type header (" application/json "). Another, better, solution is to just read the string from the from the request stream: [HttpPost] public IActionResult PostString() { using v...