Skip to main content

Posts

Showing posts from January, 2024

.NET 8–Refresh memory limit

With more and more workloads running in the cloud, optimizing the resource consumption becomes an important feature of every application. Being able to dynamically scale down the memory limit can help us reduce costs when demand decreases. However before .NET 8, when a service tried to decrease the memory limit on the fly, it could fail as the .NET garbage collector was unaware of this change and would still allocate more memory. No longer in .NET 8!  A new API was introduced that allows to adjust the memory limit on the fly: This will instruct the garbage collector to reconfigure itself by detecting the various memory limits on the system. Calling this API can result in an InvalidOperationException when the newly set limit is lower than what's already committed. Remark: For smaller workloads it can also be useful to switch from Server GC to Workstation GC, which optimizes for lower memory usage. The switch can be done by adding this flag to your csproj file: More inf...

Azure Static Web App–Inject snippets

As a follow-up on the presentation I did at  CloudBrew  about Azure Static Web Apps I want to write a series of blog posts. Part I - Using the VS Code Extension Part II - Using the Astro Static Site Generator Part III  – Deploying to multiple environments Part IV – Password protect your environments Part V – Traffic splitting Part VI – Authentication using pre-configured providers Part VII – Application configuration using staticwebapp.config.json Part VIII – API Configuration Part IX(this post) – Injecting snippets Before I continue with authentication and authorization, I want to spend one last post on configuration and more specifically on snippets . Snippets is custom code that can be injected into the head or body elements at runtime. This is useful to inject for example analytics scripts (Google Analytics, Application Insights, …) or global UI elements. Adding a snippet Open your Static Web App in the Azure Portal and go to Configuration : Select the Sn...

Azure Static Web App–API configuration

As a follow-up on the presentation I did at  CloudBrew  about Azure Static Web Apps I want to write a series of blog posts. Part I - Using the VS Code Extension Part II - Using the Astro Static Site Generator Part III  – Deploying to multiple environments Part IV – Password protect your environments Part V – Traffic splitting Part VI – Authentication using pre-configured providers Part VII – Application configuration using staticwebapp.config.json Part VIII(this post) – API Configuration In the last post in this series, I talked about the application configuration. But an Azure Static Web App can be a combination of an application part and an API part. Today we’ll have a look on how to configure the API part. Storing values API configuration settings can be set through the Azure Portal or Azure CLI and are stored in the backend of your Azure Static Web App in an encrypted format. Azure Portal To set a configuration value through the Azure Portal, go to Conf...

GetHashCode() in .NET Core

If you ever had to implement the Equals() method to compare two instances of a type in .NET, you had to implement the GetHashCode() method too. The GetHashCode method returns a numeric value which is used to identify an object during equality testing. It can also serve as an index for an object in a collection. The purpose of the method is to create a key for hashtable. It is by design useful for only one thing: putting an object in a hash table. It is faster to use the return value of GetHashCode to determine whether two objects are equal than to call the default implementation of Equals on the object type. In other words, GetHashCode is used to generate a unique identifier for an object that can be used to compare it with other objects. It is used internally by the .NET framework for quick comparisons. If you had to implement the GetHashCode method, there were some rules that should be followed which could make it quite a challenge to implement it correctly: ...

MassTransit–Avoid losing messages

At one of my clients we had a situation where messages got lost after sending them to RabbitMQ. This is quite bad as the whole point of having a message based solution was to improve the reliability of our solutions(even when of the involved systems is offline or unavailable). In this post I want to explain what got wrong and how we introduced a solution to prevent this from happening in the future. To understand the problem I first have to explain the concept of an exchange. In RabbitMQ, exchanges are message routing agents that are responsible for routing messages to different queues with the help of header attributes, bindings, and routing keys. A producer never sends a message directly to a queue. Instead, it uses an exchange as a routing mediator. Therefore, the exchange decides if the message goes to one queue, to multiple queues, or is simply discarded. Let me emphasize one sentence here: In RabbitMQ , a producer never sends a message directly to a queue Only que...

Azure Static Web App– Application configuration using staticwebapp.config.json

As a follow-up on the presentation I did at CloudBrew about Azure Static Web Apps I want to write a series of blog posts. Part I - Using the VS Code Extension Part II - Using the Astro Static Site Generator Part III  – Deploying to multiple environments Part IV – Password protect your environments Part V – Traffic splitting Part VI – Authentication using pre-configured providers Part VII(this post) – Application configuration using staticwebapp.config.json Before I continue with the authentication and authorization part, I want to take a side step into configuration. When talking about configuring a static web app, we have to make a difference between: Application configuration : This allows us to configure the application behavior and features and is managed through  the staticwebapp.config.json file. Use this file to define route and security rules, custom headers, and networking settings. Build configuration : Tweak th...

MassTransit–.NET 8 upgrade warnings

After upgrading to MassTransit 8.1, I got a list of warnings. In this post I'll walk you through the list of warnings and how I fixed them. Let's get started... ConsumerDefinition warning The first warning I got was the following: 'ConsumerDefinition<T>.ConfigureConsumer(IReceiveEndpointConfigurator, IConsumerConfigurator<T>)' is obsolete: 'Use the IRegistrationContext overload instead. Visit https://masstransit.io/obsolete for details.' That is an easy one to fix, I had to rewrite my original ConsumerDefinition: To a version that uses the IRegistrationContext as one of the parameters: InMemory Outbox warning A second warning was related to the usage of the InMemoryOutbox: 'InMemoryOutboxConfigurationExtensions.UseInMemoryOutbox(IConsumePipeConfigurator, Action<IOutboxConfigurator>)' is obsolete: 'Use the IRegistrationContext overload instead. Visit https://masstransit.io/obsolete for details.' Here is the ...

MassTransit–.NET 8 upgrade errors - No service for type 'MassTransit.Saga.ISagaRepositoryContextFactory`1[MassTransit.JobTypeSaga]' has been registered.

While upgrading an application to .NET 8 (and upgrading to the latest MassTransit version along the way), I stumbled over some Masstransit specific issues after the upgrade. The first error I got after upgrading my application to .NET 8 was the following: No service for type 'MassTransit.Saga.ISagaRepositoryContextFactory`1[MassTransit.JobTypeSaga]' has been registered. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)    at MassTransit.DependencyInjection.DependencyInjectionSagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, Func`3 send) in /_/src/MassTransit/DependencyInjection/DependencyInjection/DependencyInjectionSagaRepositoryContextFactory.cs:line 85    at MassTransit.DependencyInjection.DependencyInjectionSag...

Azure Pipelines error - User lacks permission to complete this action. You need to have 'ReadPackages'.

I blogged before about the following Azure Pipelines error wen trying to do a NuGet restore: ##[error]The nuget command failed with exit code(1) and error(Unable to load the service index for source https://tfs.server.be/tfs/DefaultCollection/_packaging/797f899f-9ad1-4158-93bc-8f3293cf4a59/nuget/v3/index.json. Response status code does not indicate success: 403 (Forbidden - User 'Build\534a066a-3992-4851-a816-b189836bee69' lacks permission to complete this action. You need to have 'ReadPackages'. (DevOps Activity ID: 8D53BF1D-E45E-49C4-879F-6CBD8635D1CE)). Although the solution I mentioned in the original blogpost should work, I found a different solution that should also do the trick. Here are the steps: Go to the Azure DevOps project that contains the failed pipeline in Azure DevOps. Go to Artifacts Select the feed that causes the problem from the drop down (if not selected by default) Click the Feed Setting gear on the top right corner. ...

Batching work in SQL Server

In one of our ASP.NET Core applications, I added a new feature to cleanup old data. My implementation was simple and used a BackgroundService to run a cleanup script on periodic intervals: All worked fine during development and testing, but when I deployed it to production it brought the whole application to a halt. What was happening? First, as this was the first time the script was run on production, there was a lot of old data. So while the query executed and completed quite fast on other environments, on production it impacted millions of rows. What made the problem even worse is that the table that should be cleaned up contained a large amount of binary data. This made the transaction log grow in size and further increased the query duration. My first attempt to improve the performance of this query was to delete the data based on the primary key. A suggestion I found here: How to Delete Large Amounts of Data – SQLServerCentral However the impact of this change was m...

.NET 8– System.Text.Json serializer error

I really like the System.Text.Json source generator as a way to optimize your API performance by reducing the serialization/deserialization cost. However after upgrading to .NET 8 I not only got some warnings , one of my applications failed during execution with the following error message: System.NotSupportedException: JsonTypeInfo metadata for type 'System.Collections.Generic.List`1[OrderDto]' was not provided by TypeInfoResolver of type ‘JsonContext'. If using source generation, ensure that all root types passed to the serializer have been annotated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.    at System.Text.Json.ThrowHelper.ThrowNotSupportedException_NoMetadataForType(Type type, IJsonTypeInfoResolver resolver)    at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)...

Azure Static Web App - Authentication using pre-configured providers

As a follow-up on the presentation I did at  CloudBrew  about Azure Static Web Apps I want to write a series of blog posts. Part I - Using the VS Code Extension Part II - Using the Astro Static Site Generator Part III  – Deploying to multiple environments Part IV – Password protect your environments Part V – Traffic splitting Part VI(this post) – Authentication using pre-configured providers I ended 2023 with a post about protecting access to your Azure Static Web App using a password. Of course this is a poor man’s implementation of security. So let us have a look today on how to properly integrate authentication in our Azure Static Web App. Authentication in itself is a broad topic, we can further refine it in 2 parts: Who are you? The real authentication part What are you allowed to do? This is more a question of authorization instead of authentication Let us focus on the first question in this post. To allow a Static Web App to know who you are we nee...