Skip to main content

Posts

Showing posts from May, 2025

.NET 9–OpenAPI and Scalar–Passing an API key

Let's continue our joruney in discovering Scalar . Today I want to talk about how we can integrate security. Most API's that we build today are secured in a way. This could be as simple as an API key or as complex as using OAuth with PKCE. In this post we’ll look at how to pass an API key through the Scalar UI. Let’s dive in… I assume that you already have registered an authentication scheme for your API like this: Now we need to write an extra transformer to include the authentication information in our OpenAPI metadata. Don’t forget to register this transformer in our OpenAPI configuration: At the Scalar level we don’t have to change anything: But if we now browse to the Scalar UI, the authentication scheme is recognized and we get the option to pass an API key:   Nice! More information .NET 9–OpenAPI and Scalar–Introduction .NET 9–OpenAPI and Scalar–Adding custom headers

Get an overview of task duration of Windows Scheduled Tasks

A long time ago, we made the decision to implement some features using batch processes that were scheduled to run at night (most of them as scheduled tasks). Over time the list of batch processes has further grown, with 85 processes running almost every night today. A sad record... Our business has further evolved and were it originally made sense to schedule all this work outside the regular business hours, we now encounter the following issues: The list of remaining free time slots is getting smaller and smaller, making it almost impossible to schedule a new task without interfering with other tasks. As our datasets have grown over the years, these processes typically also take longer and longer to execute. Our customers are interacting with our services more and more outside the regular business hours. It is no longer acceptable for our business to have to wait for some data. Realtime info is key to take correct business decisions. Some of these batch processes ar...

Generate Terraform configuration files from your Azure resources

While everyone is focusing all the announcements at Build 2025, I'm still processing some of the older recently announced features. A feature that I am happy that is finally available in preview is the Terraform export functionality in the Azure Portal. A similar feature already exists for some time for ARM and Bicep but now we can finally export to Terraform configuration files as well. Let’s give it a try… A short walkthrough Go to the Azure portal and browse to a specific resource. From there go to the Automation section and click on Export template . Click on the Terraform tab. The first time I did this I got the error below:   The reason is that you first need to register the Microsoft.AzureTerraform resource provider at the subscription level. Go to your Subscription in Azure. There open the list of Resource Providers .   Search for Microsoft.AzureTerraform resource provider and click on Register .   It can take some ...

The (non) sense of organization charts

Today while explaining my son how our heating system works, it brought me back to my earlier post about organization charts. Same as in heating system where you have a heating loop and a control loop, 2 loops exist in every organization. The first is formal and visible—it's drawn out in neat boxes and lines as your organizational chart, showing who reports to whom and where decisions get made. The second is informal and largely invisible—it's the actual pathways through which information, ideas, and real work flow to get things done. The two flows of organizational systems When we apply systems thinking to organizations, we can identify two critical flows that determine how effectively an organization functions: Control flow represents the formal authority structure—who has decision-making power, who approves what, and how accountability flows up and down the hierarchy. This is what your org chart captures beautifully with its clean boxes and reporting lines. Informat...

.NET 9–OpenAPI and Scalar–Adding custom headers

In this post I continue my investigation of using Scalar as an alternative to Swashbuckle that I was using before to expose my OpenAPI metadata in a userfriendly way. If you have no idea what Scalar is, I would recommend to check out my introduction post first before you continue reading. Today I want to have a look at how we can transform the OpenAPI metadata. On this specific API, it is expected that one of a set of custom headers is passed when calling the API. To simplify the experience, I originally created  an IOperationFilter for Swashbuckle to show these extra headers: How to customize the OpenAPI metadata in .NET 9? The generated OpenAPI document can be customized using “transformers”, which can operate on the entire document, on operations, or on schemas. Transformers are classes that implement the IOpenApiDocumentTransformer , IOpenApiOperationTransformer , or IOpenApiSchemaTransformer interfaces. Each of these interfaces has a single async method that receives...

The servant leadership paradox - When org charts contradict culture

In boardrooms and mission statements across the globe, "servant leadership" has become the philosophy du jour. Leaders proudly proclaim their commitment to serving their teams, inverting the traditional power structure, and putting employees first. Yet something curious happens when you ask to see their organizational charts. There they are—the familiar pyramids with executives perched at the top, managers in the middle, and the frontline workers—those actually creating value—relegated to the bottom or, in many cases, not represented at all. This visual contradiction begs the question: Can an organization truly embody servant leadership when its very structure portrays the opposite relationship? The telling power of visuals I think that organizational charts are more than administrative tools—they're powerful symbols that communicate "how things really work around here." When leadership teams espouse servant leadership while maintaining traditional hiera...

.NET 9–OpenAPI and Scalar–Introduction

With the release of .NET 9 , Microsoft has removed Swashbuckle from the default Web API templates. If you have never heard about Swashbuckle before, it allowed you to generate OpenAPI metadata for your web api's. Although I had no complaints using the Swagger UI, I decided to use the opportunity to have a look at library, Scalar, to generate an UI based on the OpenAPI documentation. In this post, I’ll walk you through my transition from Swashbuckle to Scalar, highlighting the benefits, challenges, and key implementation steps. Why the change? Microsoft decided to drop Swashbuckle due to maintenance issues and a shift toward integrated OpenAPI support . While Swashbuckle provided automatic documentation , Swagger UI integration , and customizability , Scalar introduces a sleek UI , mobile-friendly interface , and enhanced search capabilities . Scalar not only provides great integration for .NET but also works on a lot of other platforms. Setting Up Scalar in .NET 9 To i...

Why you should clean up your test directories

Today I lost a lot of time investigating a stupid(aren’t they all?) issue with some failing tests on the build server. The strange thing was that when I ran the same tests locally, they always succeeded...what was going wrong? Just for completeness, here is the test task configuration I was using: Nothing special I would think. It was only when diving deeper into the build output that I discovered what was going wrong. Here is the output that explains the problem: 2025-05-20T13:19:22.3855459Z vstest.console.exe 2025-05-20T13:19:22.3855564Z "D:\b\3\_work\210\s\IAM.Core.Tests\bin\Release\ net6.0\IAM.Core.Tests.dll " 2025-05-20T13:19:22.3855657Z "D:\b\3\_work\210\s\IAM.Core.Tests\bin\Release\ net8.0\IAM.Core.Tests.dll " 2025-05-20T13:19:22.3855761Z "D:\b\3\_work\210\s\Mestbank.Core.Tests\bin\Release\net6.0\Mestbank.Core.Tests.dll" 2025-05-20T13:19:22.3855857Z "D:\b\3\_work\210\s\Mestbank.Core.Tests\bin\Release\net8.0\Mestbank.Core.Tests....

Static File handling in ASP.NET Core 9.0

I know, I know, .NET 10 is already in preview and I am still catching up on what was added to .NET 9.0. Today while upgrading an older application to .NET 9, I decided to have a look at the new static file handling introduced in .NET 9 through the MapStaticAssets feature. Static File middleware (before .NET 9) Before .NET 9, static files(Javascript, CSS, images, …) were handled through the UseStaticFiles middleware This middleware is still there as the new MapStaticAssets feature does not support all the features that the original middleware had. From the documentation : Serving files from disk or embedded resources, or other locations Serve files outside of web root Set HTTP response headers Directory browsing Serve default documents FileExtensionContentTypeProvider Serve files from multiple locations Serving files from disk or embedded resources, or other locations Serve files outside of web root Set HTTP response headers Direc...

WSFederation broken after upgrade to .NET 8

This week a colleague contacted me with an issue he encountered after upgrading to .NET 8.0. On the project involved we were using the WsFederation middleware to authenticate and interact with ADFS. However after upgrading to .NET 8 and the 8.x version of the Microsoft.AspNetCore.Authentication.WsFederation middleware the trouble began. Using this version resulted in a change in behavior as suddenly the middleware starts to expect a SAML 2.0 token instead of a SAML 1.1 token that is now issued by our ADFS server: XmlReadException: IDX30011: Unable to read XML. Expecting XmlReader to be at ns.element: 'urn:oasis:names:tc:SAML:2.0:assertion.Assertion', found: 'urn:oasis:names:tc:SAML:1.0:assertion.Assertion'. Although I found a post online that it would be technically possible to let ADFS return a SAML 2.0 token through WSTrust, this doesn’t fit in the passive federation scenario we had, so time to look at some alternative solutions. Attempt 1 – Reverting to an ...

Troubleshooting a SQL timeout issue

I got contacted by someone from my team that INSERTs were failing on one of our database instances. A look at Application Insights showed the following error message in the logs: System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. For an unknown reason, the transaction timeout before it could be committed resulting in a rollback operation and a failing INSERT.  Time to open SQL Server Management Studio and first take a look at the Resource Locking Statistics by Objects report: Indeed, multiple sessions share a lock on the same table. If you want, you can also check the User Statistics report to find out what these sessions are related to:   To fix the issue, I killed the sessions that were causing the lock: KILL 236 KILL 210 KILL 257 After doing that, I could confirm that the locking was gone by refreshing the report: More information Sql...

Managing technical debt like financial debt

Yesterday on my way home, I was listening to the SoftwareCaptains podcast episode with Mathias Verraes (sorry, the episode is in Dutch). One of the topics discussed was technical debt and the  question was raised why (most) organizations manage very carefully their financial debt, they don’t apply the same rigor for their technical debt. This triggered a train-of-thought that resulted in this post. Financial debt is meticulously tracked, reported, and managed. CFOs provide regular updates to boards about debt levels, leveraging ratios, and debt servicing costs. Detailed financial statements outline current liabilities, long-term obligations, and repayment schedules. Financial debt is visible, quantified, and actively managed. Yet technical debt—which can be just as crippling to an organization's future—often exists as an invisible, unquantified burden until it's too late. What if we managed technical debt with the same rigor as financial debt? The hidden cost of techni...

How to limit memory usage of applications in IIS

A while back I talked about a memory leak we had in one of our applications. As a consequence, it brought the full production environment to a halt impacting not only the causing application but all applications hosted on the same IIS instance. Although we found the root cause and fixed the problem, we did a post-mortem to discuss on how to avoid this in the future. In this post, I'll walk you through the practical strategies we implemented to limit and optimize memory usage for our applications running in Internet Information Services (IIS). n this guide, I'll walk you through practical strategies to limit and optimize memory usage for applications running in Internet Information Services (IIS). Understanding memory usage in IIS Before diving into solutions, it's important to understand how IIS manages memory. IIS runs web applications in application pools, which are processes (w3wp.exe) that host your web applications. Each application pool can consume memory ind...

Azure DevOps– Obsolete check-in policies

Today I had to make a fix in an old project that was still using Team Foundation Version Control (TFVC). It immediately made me appreciate GIT a lot more but that is not what I want to talk about today. After making my changes I had to check-in my changes (remark: commit my changes if you want to use the GIT terminology). One of the features that TFVC had to offer was the concept of check-in policies, rules that could be checked and validated before you can check-in your changes in the central source repository. This was a feature we used a lot to improve the quality of the code and capture some mistakes as soon as possible. This time when I tried to check-in my changes, I noticed the following warning in Visual Studio: Obsolete policies are being applied and should be updated. This is because the way that TFVC check-in policies are stored in Azure DevOps has changed. This migration is required for keeping TFVC check-in compatible with the future Azure DevOps versions. The good...

Compliancy vs Commitment

I don't see criticism and (a certain level of) conflict as unhealthy in an organization. The contrary! It is when people stop raising their voice and sharing their feedback that you need to start worrying. It could be a sign that people no longer care and have decayed from commitment to compliance. Beyond following orders As leaders we are constantly seeking ways to drive results. But there's a fundamental distinction worth understanding on how to achieve this:  If we collaborate, the result is commitment. If we coerce, the result is compliance. Commitment comes from within, whereas compliance is forced by an external source. When people comply, they're simply following orders. They do just enough to get by, meet the bare minimum requirements, or check the box. There's no personal investment in the outcome. Commitment, on the other hand, invites full participation, engagement, and discretionary effort. The language of Commitment L. David Marquet states in his ...

Meet the Phi family

The Phi family keeps growing with the recent introduction of the Phi-4-Reasoning, Phi-4-mini and Phi-4-multimodal models. These new models introduce some great enhancements we'll discuss later in this post. But maybe let me start by introducing you to the Phi family. The Phi family The Phi family is a set of small language models created and maintained by Microsoft Research. They are designed to achieve strong performance while being much smaller and more efficient than their larger counterparts like GPT-4 or Claude. Phi’s evolution over the last year has continually pushed this envelope of quality vs. size, expanding the family with new features to address diverse needs. Where the original Phi models focussed mostly on chat and coding activitities, capabilities have now extended to multimodel (vision, speech), function calling and advanced reasoning. Function calling support A feature I’m especially happy with that it finally got introduced into the Phi models is funct...

.NET Conf Focus on Modernization

I don’t know what happened but somehow I succeeded to miss the latest .NET Conf Focus edition. And this time, it was all about a topic that every developer has to handle sooner or later during his professional career; Application Modernization! Here was the original announcement: Get Ready for .NET Conf: Focus on Modernization | Microsoft Community Hub and a screenshot from the agenda: The good news is all the content is available on YouTube here: .NET Conf - Focus on Modernization: Day 1 I’m especially interested in the session about the upcoming AI-assisted tooling to upgrade .NET apps. With the current pace at which new(er) LTS versions of .NET are released, any help to keep these applications supported and up-to-date is more then welcome:

Angular 18–Referencing assets

Yesterday I wrote about a pet project I'm working that is using Angular 19. Turns out that some things have changed compared to previous versions. But where I discovered yesterday that a new build output structure was used, today I struggled with the handling of static assets. In older Angular versions, static application assets could be added to the src\assets folder and loaded from there in your application html. However starting from Angular 18 the src\assets folder is no longer there, instead a new assets option configuration exists in your angular.json . When creating a new project, this is configured by default to load assets from a public folder: The assets configuration is build up using a combination of 3 elements: glob: the pattern used to find matching files (e.g. **/*) input: the input directory where this pattern should be applied (e.g. public) output: the absolute path within the output where the matching assets should be copied to This confi...

Azure Static Web Apps - Failed to find a default file in the app artifacts folder. Valid default files: index.html,Index.html.

For a pet project I'm working on, I created a new Angular application using Angular 19. I used the same Github Actions setup I was using for my other projects. However, this time, the build failed with the following error message: Failed to find a default file in the app artifacts folder (dist/treasurehunt). Valid default files: index.html,Index.html. If your application contains purely static content, please verify that the variable 'app_location' in your workflow file points to the root of your application. If your application requires build steps, please validate that a default file exists in the build output directory. Here is the GitHub Actions file that was used: Important to notice here are the following settings: app_location: This is the location where the Azure Static Web App build task looks for the source code output_location: This is the location where the Azure Static Web App looks for the final application. This should match with your ...

Optimize the whole organization not the different parts

The last weeks I'm thinking a lot about organization design and how to improve/optimize our organization. I see well-intentioned improvement initiatives launched with enthusiasm, only to deliver disappointing results. Despite the energy invested, we're not seeing the transformation we hoped for. Why? A possible answer could be found in this statement from Russel L. Ackoff that he did in the video below: If we have a system of improvement that’s direct at improving the parts taken separately, you can be ABSOLUTELY sure that the performance of the hole will not be improved. The trap of reductionist thinking What’s possibly happening here is that we are falling into a common trap—what systems thinkers call "reductionist thinking." We break down the organization into components and try to optimize each part separately: HR launches a new performance management system IT implements a new collaboration tool Operations streamlines a specific process...