Sunday, November 12, 2023

Blazor WebAssembly Lazy Loading Changes from .NET 7 to .NET 8

Lazy Loading is an essential tool used in web client development to defer loading of resources until requested by the user, as opposed to loading everything up-front which is expensive. Blazor has had the ability to lazy load Razor Class Libraries for the last several versions of .NET, but there are some updates in .NET 8 that aren't well documented.

To not be completely repetitive, here are the basic steps for implementing lazy loading in your Blazor WebAssembly application direct from the Microsoft docs: Lazy load assemblies in ASP.NET Core Blazor WebAssembly

The issue is the Project Configuration and Router Configuration sections of the docs as of this post are still not up to date. With .NET 8, the WASM assemblies are now built as .wasm files not .dll files and therefore the main update you'll need to make are inside the .csproj file and within the definition of the LazyAssemblyLoader routing code to use the .wasm file extension for the referenced .dlls:

.csproj file updates

Routing file updates

If continuing to use the old code with the .dll extension you would get the following error on building your application:
Unable to find 'EngineAnalyticsWebApp.TestLazy.dll' to be lazy loaded later. Confirm that project or package references are included and the reference is used in the project" error on build
Upon making the required updates to your .NET 8 application to prevent the error above, your app should successfully build, and you'll see the correct deferred execution in the browser.

Friday, November 3, 2023

Dealing with Time Skew and SAS Azure Blob Token Generation: 403 Failed to Authenticate Error

If you're working with the Azure.Storage.Blobs SDK in .NET and generating SAS tokens, you might come across an error like the following when making a call to GetUserDelegationKeyAsync():
Status 403: The request is not authorized to perform this operation using this permission

Here is a sample of code that might throw this error in which the startsOn value is set to the current time:

Before you start double checking all of the user permissions in Azure and going through all the Access Control and Role Assignments in Blob Storage (assuming you do have them configured correctly), this might be a red herring for a different issue with the startsOn value for the call to GetUserDelegationKeyAsync(). The problem is likely with clock skew and differences in times from the server and client.

It is documented in SAS best practices from the Azure docs (found here), the following issue with clock skew and how to remedy the issue:

Be careful with SAS start time. If you set the start time for a SAS to the current time, failures might occur intermittently for the first few minutes. This is due to different machines having slightly different current times (known as clock skew). In general, set the start time to be at least 15 minutes in the past. Or, don't set it at all, which will make it valid immediately in all cases. The same generally applies to expiry time as well--remember that you may observe up to 15 minutes of clock skew in either direction on any request. For clients using a REST version prior to 2012-02-12, the maximum duration for a SAS that does not reference a stored access policy is 1 hour. Any policies that specify a longer term than 1 hour will fail.

There is a simple fix for this as instructed to modify the startsOn value to be either not set or 15 minutes (or greater) in the past. With this updated code, the 403 error is fixed and will proceed as expected.