Showing posts with label azure. Show all posts
Showing posts with label azure. Show all posts

Reading Notes #706

This week's collection highlights several practical upgrades for your workflow, ranging from cleaner C# patterns to more secure ways to manage AI agents. I’ve also included a few podcast episodes and articles that offer some much-needed perspective on productivity and community life.


AI

  • Why AI Agents Need Isolation with Docker SBX (Karan Verma) - Power comes with responsibilities. It's well known (at least for Spider-Man fans), but more seriously, AI users have a simple way to stay safe. And now, with "the kits", it looks like it's even easier.

  • Using AI to Build a Blazor App 1: Start With the Problem (Jon Hilton ) - It's so true that AI doesn't always do or act the way we expect. In this case, I wonder if a different model would have been better. In my experience, GPT is better at doing things compared to brainstorming.

Databases

Programming

DevOps

  • New: Versioned CLI and SDK Docs (Cam Soper) - That's a nice feature that more should implement! You pick your API version, and the documentation follows.

Podcasts

Miscellaneous

  • 3 Tricks to Help You Stop Procrastinating (Suzanne Scacca ) - Need tips to improve your time management? This post is for you.

  • Goodbye, forever, probably. (Salma) - Sad news for the communities, but at the same time, it's because of those same communities. This post shares a very sad portrait of the online world that affects many people.

~frank


Reading Notes #705

This week’s collection features a mix of critical .NET lifecycle updates and practical strategies for optimizing your database interactions. These selected articles offer helpful insights into everything from edge computing deployments to the evolving landscape of AI in modern workflows.


AI

  • AI Raised the Bar (And Now We're All Tired) (Golnaz) - It's so true! So much can be done quickly today. An interesting question is: how do we avoid burning out resources and tokens? How, as human we stay smart? After all, life is a marathon, not a sprint!

Cloud

Databases

DevOps

Programming

Miscellaneous

~frank


Reading Notes #704

This week’s collection highlights practical ways to improve developer workflows, from faster test runs and more manageable pull requests to intuitive new AI integrations. I have gathered a few standout articles on Blazor components, Azure Functions updates, and the nuances of training coding agents for your specific stack.

Suggestion of the week

Programming

Open Source

DevOps

AI


Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week. 

 ~frank


Reading Notes #702

This week’s compilation explores a mix of critical topics ranging from integrating AI models with SQL Server to navigating the complexities of Azure container troubleshooting. I’ve selected these particular articles because they offer practical ways to streamline your workflow and better understand the latest shifts in cloud infrastructure and software development.

Databases

AI

Cloud

DevOps

Miscellaneous

Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week. 

 ~frank

Reading Notes #692

The tech landscape is constantly evolving, and keeping up with the latest developments can be overwhelming. From AI-powered tools like Ollama and OpenClaw, to new ways of programming with Aspire Docs and Azure CLI, it seems like there's always something new to explore. In this edition of Reading Notes, I'll share some of the interesting things that caught my eye recently, from AI advancements to developer tools and beyond.


Suggestion of the week

AI

Programming

Cloud

Miscellaneous


Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, podcasts and books that catch my interest during the week.

If you have interesting content, share it!

~frank

Reading Notes #687

Welcome to this new Reading Notes post, a collection of interesting articles and resources I've been absorbing lately! This week's roundup dives into a variety of topics, from practical storage solutions and leveraging AI for code upgrades to exploring the intersection of AI and business value. Get ready for a diverse mix of tech insights and management reflections.


Programming

AI

Books



The Making of a Manager: What to Do When Everyone Looks to You
(Julie Zhuo) - Most management books are written by advanced managers, people with a lot of experience who already have the "manager" mindset well established in their heads. This book feels different, more accessible, closer to a conversational tone. In this book, Julie shares her stories of becoming a manager and the advice she learned along the way. I think it's a good book to get started on this topic, especially if you are new to that position or thinking about it, to understand and be better equipped for the new challenges coming your way.


Miscellaneous

~frank



Reading Notes #684

Balancing cloud innovation with AI practicality, this week’s notes blend Azure updates, .NET’s AI roadmap, and clever Python hacks. A sharp reminder on burnout prevention anchors the mix, while creative teams and DevOps culture inspire fresh perspectives. From Docker model runners to Git worktrees, every corner here offers actionable insights or a spark of curiosity, no clichés, just tools and truths for developers navigating the stormy seas of tech.


Suggestion of the week

Cloud

AI

Podcasts

Miscellaneous

~frank

Reading Notes #682

This week’s Reading Notes bring together programming tips, AI experiments, and cloud updates. Learn to build Python CLI tools. Untangle GitHub issue workflows. Try running AI models locally. Catch up on Azure news. And explore ideas around privacy and cloud architecture. Short reads. Useful takeaways.


Programming

AI

Miscellaneous

~frank

Reading Notes #673

This week’s notes focus on where AI meets everyday development: Copilot and Azure for tighter, faster workflows, a thoughtful overhaul of Aspire’s deploy CLI, and a hands‑on look at building MCP servers in C#. Security threads through it all with practical DevSecOps and Shadow IT reminders plus podcast picks on teaching, acronyms, and tackling imposter syndrome.


AI

Programming

Podcasts

Miscellaneous

Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week.

If you have interesting content, share it!

~frank

Reading Notes #667

This week post explores the intersection of AI, cloud, and DevOps, featuring updates on Microsoft’s Logic Apps integration, practical .NET tools for system automation, and strategies to enhance documentation for AI-driven workflows. Whether you’re refining enterprise security practices with NuGet’s Trusted Publishing or diving into the ethical nuances of AI through vector databases, this post offers a blend of technical deep dives and thought-provoking discussions. Don’t miss the podcast highlights, from DevOps innovation to the business impact of employee well-being, perfect for developers, architects, and curious minds alike. Let’s connect the dots in a world where code, creativity, and collaboration drive progress.






Programming

AI

DevOps

Podcasts

Miscellaneous

Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week.

If you have interesting content, share it!

~frank

Reading Notes #658

This week, we explore the latest insights on AI, Cloud, and software development to keep you informed and inspired.

little branch with leaves and walnuts

Cloud

Programming

Databases

AI

Miscellaneous


Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week. 

If you have interesting content, share it! 

~frank

Reading Notes #656

This week, we're exploring a wide range of topics, from .NET 10 previews and A/B testing to the latest in Azure development and AI. Plus, a selection of insightful podcast episodes to keep you informed and inspired.

Cloud


Programming

Open Source

  • Patrik Svensson (Patrik Svensson) - An interesting way to structure the flow that provides more detailed issues and PR with a clear purpose.

AI


Podcasts


~frank

Reading Notes #655

Welcome to the 655th Reading Notes. This edition explores embedding Python in .NET, working with stacked git branches, and an introduction to cloud-native. Plus, a quick tip for the Azure Portal and using local AI for code reviews. 

a kayak on the water with a tree at the horizon

Open Source

Programming

Cloud

AI


Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week. 

If you have interesting content, share it!


~frank


Reading Notes #653

Welcome to Reading Notes #653 another packed edition of insights, tools, and updates from the tech world! This week's roundup dives into legendary engineering wisdom, AI controversies, and the latest innovations in Docker, Azure, and VS Code. Whether you're exploring MCP, refining your scripting skills, or gearing up for the newest Azure Developer CLI release, there's something here for every developer.

windmill on the cap of Ile Perrot

Let’s get into it!

Cloud

  • Azure Developer CLI (azd) - June 2025 (Kristen Womack) - Love that tool, great updates, so many new features and improvements in this version, very looking forward to try all of them, turning them all

AI

Programming

Miscellaneous


~frank

Reading Notes #652

This week, we explore a variety of topics, from database containerization and AI security risks to the evolving landscape of gaming devices and cloud technologies. We also explore the shift towards security-first development and the integration of .NET Aspire with SQL Server for integration testing.


Let's dive in!

Suggestion of the week

Cloud

Programming

Databases

Miscellaneous

~frank

Full-Stack Azure Deployment Made Easy: Containers, Databases, and More

Automating deployments is something I always enjoy. However, it's true that it often takes more time than a simple "right-click deploy." Plus, you may need to know different technologies and scripting languages.

(Version française ici)

But what if there was a tool that could help you write everything you need—Infrastructure as Code (IaC) files, scripts to copy files, and scripts to populate a database? In this post, we'll explore how the Azure Developer CLI (azd) can make deployments much easier.

What do we want to do?

Our goal: Deploy the 2D6 Dungeon App to Azure Container Apps.

This .NET Aspire solution includes:

  • A frontend
  • A data API
  • A database

Aspire resources schema


The Problem

In a previous post, we showed how azd up can easily deploy web apps to Azure.

If we try the same command for this solution, the deployment will be successful—but incomplete:

  • The .NET Blazor frontend is deployed perfectly.
  • However, the app fails when trying to access data.
  • Looking at the logs, we see the database wasn't created or populated, and the API container fails to start.

Let's look more closely at these issues.

The Database

When running the solution locally, Aspire creates a MySQL container and executes SQL scripts to create and populate the tables. This is specified in the AppHost project:

var mysql = builder.AddMySql("sqlsvr2d6")
                   .WithLifetime(ContainerLifetime.Persistent);
                
var db2d6 = mysql.AddDatabase("db2d6");

mysql.WithInitBindMount(source: "../../database/scripts", isReadOnly: false);

When MySQL starts, it looks for SQL files in a specific folder and executes them. Locally, this works because the bind mount is mapped to a local folder with the files.

However, when deployed to Azure:

  • The mounts are created in Azure Storage Files
  • The files are missing!

The Data API

This project uses Data API Builder (dab). Based on a single config file, a full data API is built and hosted in a container.

Locally, Aspire creates a DAB container and reads the JSON config file to create the API. This is specified in the AppHost project:

var dab = builder.AddDataAPIBuilder("dab", ["../../database/dab-config.json"])
                .WithReference(db2d6)
                .WaitFor(db2d6);

But once again, when deployed to Azure, the file is missing. The DAB container starts but fails to find the config file.

Logs of DAB failing to start


The Solution

The solution is simple: the SQL scripts and DAB config file need to be uploaded into Azure Storage Files during deployment.

You can do this by adding a post-provision hook in the azure.yaml file to execute a script that uploads the files. See an example of a post-provision hook in this post.

Alternatively, you can leverage azd alpha features: azd.operations and infraSynth.

  • azd.operations extends the provisioning providers and will upload the files for us.
  • infraSynth generates the IaC files for the entire solution.

💡Note: These features are in alpha and subject to change.

Each azd alpha feature can be turned on individually. To see all features:

azd config list-alpha

To activate the features we need:

azd config set alpha.azd.operations on
azd config set alpha.infraSynth on

Let's Try It

Once the azd.operation feature is activated, any azd up will now upload the files into Azure. If you check the database, you'll see that the db2d6 database was created and populated. Yay!

However, the DAB API will still fail to start. Why? Because, currently, DAB looks for a file, not a folder, when it starts. This can be fixed by modifying the IaC files.

One Last Step: Synthesize the IaC Files

First, let's synthesize the IaC files. These Bicep files describe the required infrastructure for our solution.

With the infraSynth feature activated, run:

azd infra synth

You'll now see a new infra folder under the AppHost project, with YAML files matching the container names. Each file contains the details for creating a container.

Open the dab.tmpl.yaml file to see the DAB API configuration. Look for the volumeMounts section. To help DAB find its config file, add subPath: dab-config.json to make the binding more specific:

containers:
    - image: {{ .Image }}
      name: dab
      env:
        - name: AZURE_CLIENT_ID
          value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
        - name: ConnectionStrings__db2d6
          secretRef: connectionstrings--db2d6
      volumeMounts:
        - volumeName: dab-bm0
          mountPath: /App/dab-config.json
          subPath: dab-config.json
scale:
    minReplicas: 1
    maxReplicas: 1

You can also specify the scaling minimum and maximum number of replicas if you wish.

Now that the IaC files are created, azd will use them. If you run azd up again, the execution time will be much faster—azd deployment is incremental and only does "what changed."

The Final Result

The solution is now fully deployed:

  • The database is there with the data
  • The API works as expected
  • You can use your application!
2D6 Dungeon App deployed


Bonus: Deploying with CI/CD

Want to deploy with CI/CD? First, generate the GitHub Action (or Azure DevOps) workflow with:

azd pipeline config

Then, add a step to activate the alpha feature before the provisioning step in the azure-dev.yml file generated by the previous command.

- name: Extends provisioning providers with azd operations
  run: azd config set alpha.azd.operations on     

With these changes, and assuming the infra files are included in the repo, the deployment will work on the first try.

Conclusion

It's exciting to see how tools like azd are shaping the future of development and deployment. Not only do they make the developer's life easier today by automating complex tasks, but they also ensure you're ready for production with all the necessary Infrastructure as Code (IaC) files in place. The journey from code to cloud has never been smoother!

If you have any questions or feedback, I'm always happy to help—just reach out on your favorite social media platform.

In Video

Here the video version of this blog post.


References


Reading Notes #647


This post is a collection of my latest reading notes, highlighting interesting articles and resources on AI, programming, databases, and more. Each link includes a brief summary of what I found valuable or noteworthy.
screenshot linux shutdown operations

AI


Programming


Databases


Miscellaneous

  • Help yourself to thrive (Salma) - The human body is an extraordinary machine, extremely strong and conciliant, but it also requires a fine turning. Great post, we must learn from it.


Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week. 

If you have interesting content, share it!

~Frank

Reading Notes #646

Welcome to this week's collection of fascinating reads across cloud computing, AI, and programming! As technology continues to evolve at breakneck speed, I've gathered some of the most insightful articles that caught my attention. From securing MCP servers to exploring Rust, there's something here for every tech enthusiast. 
Dive in and discover what's new in our rapidly changing digital landscape.

Cloud

AI

Programming

Sharing my Reading Notes is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week. 

If you have interesting content, share it!

~Frank

Converting a Blazor WASM to FluentUI Blazor server

TL;DR: This post walks through migrating a Blazor WebAssembly project to FluentUI Blazor server, highlighting key improvements in UI, authentication, and containerization using Azure Container Apps and .NET Aspire.

(👓Version en français ici

Why Migrate?

The migration to FluentUI Blazor server brought three major benefits:

  • 🎨 Modern UI with FluentUI components
  • 🔒 Simplified authentication using Azure Container Apps
  • 🚀 Better development experience with .NET Aspire

In this post, I'm sharing my journey while migrating a Blazor WebAssembly (WASM) project to a FluentUI Blazor server project. The goal was to use the new FluentUI Blazor components library, take advantage of .NET Aspire and be able to execute the project in a container.

Recently, I've been working on the migration of AzUrlShortener. Upgrading SDKs and packages, improving the security, and changing the architecture of the solution. This post is part of a series of posts where I share a few interesting details, tips, and tricks I learned while working on this project.

AzUrlShortener is an Open source project that consist of simple URL shortener that I built a few years ago. The goal was simple: having a budget friendly solution to share short URL that would be secure, easy to use and where the data would stay mine. Each instance is hosted in Azure and consist of an API (Azure Function), an Blazor WebAssembly website (Azure Static Web App), and Data Storage (Azure Storage table).

This post is part of a series about modernizing the AzUrlShortener project:

Migration Strategy: Fresh Start vs. Refactor

When migrating an existing project, you have two options: Editing the existing project to reshaping it into the new type or creating a new project and copy-pasting pieces of code from the old project to the new one. In this case, I chose to create a new project and copy-paste the code. This way, I could keep the old project as a backup in case something went wrong.

Creating a New Project

Like mentioned earlier I wanted to use the new FluentUI Blazor components library. It's an open-source project that provides a set of components for building web applications using the Fluent Design System. It makes it easy to create beautiful and responsive user interfaces that are consistent. To create a new project we can use the available template.

dotnet new fluentblazor -n Cloud5mins.ShortenerTools.TinyBlazorAdmin

Dark Mode & Theming Support 🌙

The one thing I do to all my FluentUI Blazor projects is to add a settings page. This page allows the user to change the theme and color of the application. I should do a template to save time, but until then here the required code to add the settings page.

Settings.razor

Let's start by creating that new page called Settings.razor. With two selects, one for the theme (dark or light) and one for the accent color.

@page "/settings"

@using Microsoft.FluentUI.AspNetCore.Components.Extensions

@rendermode InteractiveServer

<FluentDesignTheme @bind-Mode="@Mode"
				   @bind-OfficeColor="@OfficeColor"
				   StorageName="theme" />

<h3>Settings</h3>

<div>
	<FluentStack Orientation="Orientation.Vertical">
		<FluentSelect   Label="Theme" Width="150px"
						Items="@(Enum.GetValues<DesignThemeModes>())"
						@bind-SelectedOption="@Mode" />
		<FluentSelect   Label="Color"
						Items="@(Enum.GetValues<OfficeColor>().Select(i => (OfficeColor?)i))"
			Height="200px" Width="250px" @bind-SelectedOption="@OfficeColor">
			<OptionTemplate>
				<FluentStack>
					<FluentIcon Value="@(new Icons.Filled.Size20.RectangleLandscape())" Color="Color.Custom"
						CustomColor="@(@context.ToAttributeValue() != "default" ? context.ToAttributeValue() : "#036ac4" )" />
					<FluentLabel>@context</FluentLabel>
				</FluentStack>
			</OptionTemplate>
		</FluentSelect>
	</FluentStack>
</div>

@code {
    public DesignThemeModes Mode { get; set; }
    public OfficeColor? OfficeColor { get; set; }
}

App.razor

In the App it self, we need to some JavaScript and the loading theme component. Just after the </body> tag, we need to add the following code:

<!-- Set the default theme -->

<script src="_content/Microsoft.FluentUI.AspNetCore.Components/js/loading-theme.js" type="text/javascript"></script>

<loading-theme storage-name="theme"></loading-theme>

Imports.razor

I noticed some warning in the code about missing using directives. To fix that, find the line that reference to Components.Icons in the _Imports.razor and change it by the following. The Icons alias should resolve the problem.

@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons

MainLayout.razor

The main layout is our base page by default. We need to add Mode and OfficeColor to make the accessible to the entire application.

@code {
    public DesignThemeModes Mode { get; set; }
    public OfficeColor? OfficeColor { get; set; }
}

NavMenu.razor

The only thing left is to be able to easily access this new page. This can be done simply by adding an option in the navigation menu.

<FluentNavLink Href="/settings" Match="NavLinkMatch.All" Icon="@(new Icons.Regular.Size20.TextBulletListSquareSettings())">Settings</FluentNavLink>

Test it

And voilà! You should now have a settings page that allows you to change the theme and color of the application. This is all great and it's not really related to the migration, but it's a nice addition to have. Dark mode for the win!

The migration

The migration itself had many little pieces, but wasn't that complex. The project is part of a .NET Aspire solution, so I added the project to the solution dotnet sln add ./Cloud5mins.ShortenerTools.TinyBlazorAdmin. Then added the references to Cloud5mins.ShortenerTools.Core (the class library with all the model, and services) and the ServiceDefault project that was generated when we added Aspire to the solution.

The next logical step was to add our Blazor project the the orchestrator with those lines in the Program.cs of the AppHost project.

builder.AddProject<Projects.Cloud5mins_ShortenerTools_TinyBlazorAdmin>("admin")
	.WithExternalHttpEndpoints()
	.WithReference(manAPI);

This will make sure the TinyBlazorAdmin project starts with a reference to the API and have accessible endpoints. Without the .WithExternalHttpEndpoints() the project wouldn't be accessible once deployed to Azure.

To use the capability of .NET Aspire to orchestrate the different projects, we need to replace our previous HttpClient creation in the Program.cs of the TinyBlazorAdmin by the following code:

builder.Services.AddHttpClient<UrlManagerClient>(client => 
{
    client.BaseAddress = new Uri("https+http://api");
});

This will make sure the UrlManagerClient receives an httpClient using the correct address and port when calling the API. Let's have a look at the UrlManagerClient class and one of the method that will be used to call the API.

public class UrlManagerClient(HttpClient httpClient)
{

	public async Task<IQueryable<ShortUrlEntity>?> GetUrls()
    {
		IQueryable<ShortUrlEntity> urlList = null;
		try{
			using var response = await httpClient.GetAsync("/api/UrlList");
			if(response.IsSuccessStatusCode){
				var urls = await response.Content.ReadFromJsonAsync<ListResponse>();
				urlList = urls!.UrlList.AsQueryable<ShortUrlEntity>();
			}
		}
		catch(Exception ex){
			Console.WriteLine(ex.Message);
		}
        
		return urlList;
    }
	// ...
}

As the code shows the httpClient is injected in the constructor and used to call the API. The GetUrls method is a simple GET request that returns a list of ShortUrlEntity. The API is the one created in a previous post: How to use Azure Storage Table with .NET Aspire and a Minimal API, and all the classes are part of the Cloud5mins.ShortenerTools.Core project.

The URL Grid

Part of the migration was also to replace the Syncfusion grid by the new FluentUI Blazor Grid. Not that Syncfusion controls are not great, quite the contrary, but because the AzUrlShortener project has moved to a different owner, I think it would be better to use components that required no licenses.

For this initial iteration, the Syncfusion grid will be replace by the FluentUI Blazor Grid. In a future iteration the Syncfusion Charts component will also be replace. Thank you Syncfusion for the community license used in this project.

The code of UrlManager.razor changed quite a lot as the to grid were a bit different in there naming and usage. The sorting required a bit more code as the column name are not the same as the property name. To provide an example the "Vanity" column is in fact the RowKey property of the ShortUrlEntity class. To be able to sort the column, we need to create a GridSort object that will be used in the TemplateColumn definition.

Definition of the column in the grid:

<TemplateColumn Title="Vanity" Width="150px" Sortable="true" SortBy="@sortByVanities">
    <FluentAnchor Href="@context!.ShortUrl" Target="_blank" Aearance="Appearance.Hypeext">@context!.RowKey</FluentAnchor>
</TemplateColumn>

Definition of the GridSort object:

GridSort<ShortUrlEntity> sortByVanities = GridSort<ShortUrlEntity>.ByAscending(p => p.RowKey);

One big improvement that could be done in the future would be to use the virtual grid. The virtual grid is a great way to improve the performance of the grid when dealing with large amount of data as it only loads the data that is visible on the screen. I show how to use the virtual grid in a previous post: How use a Blazor QuickGrid with GraphQL.

Removing the fake popup div

One of the FluentUI Blazor component is the FluentUIDialogue. This component is used to display a popup window, and will help us keeping the code more structure and clean. Instead of having <div> in the code, we can typed <FluentUIDialog> and it will be rendered as a popup.

var dialog = await DialogService.ShowDialogAsync<NewUrlDialog>(shortUrlRequest, new DialogParameters()
	{
		Title = "Create a new Short Url",
		PreventDismissOnOverlayClick = true,
		PreventScroll = true
	});




Replacing the Authentication

Instead of having to implementing the authentication in the Blazor project, we will be using the a feature of Azure Container Apps that required no code changes! You don't need to change a single line of code to secure your application deployed on Azure Container Apps (ACA)! Instead, your application is automatically protected simply by enabling the authentication feature, called EasyAuth.

Once the solution is deployed to Azure the TinyBlazorAdmin will be installed in a container app named "admin". To secured it, navigate to the Azure Portal, and select the Container App you want to secure. In this case, it will be the "admin" container app. From the left menu, select Authentication and click Add identity provider.

You can choose between multiple providers, but let's use Microsoft since it's deployed in Azure and you are already logged in. Once Microsoft is chosen, you will see many configuration options. Select the recommended client secret expiration (e.g., 180 days). You can keep all the other default settings. Click Add. After a few seconds, you should see a notification in the top right corner that the identity provider was added successfully.

Voila! Your app now has authentication. Next time you navigate to the app, you will be prompted to log in with your Microsoft account. Notice that your entire app is protected. No page is accessible without authentication.

Conclusion

The migration from Blazor WebAssembly to FluentUI Blazor Server has been a successful journey that brought several meaningful improvements to the project:

  • Enhanced user interface with modern FluentUI components
  • Cleaner, more maintainable code structure
  • Simplified authentication using Azure Container Apps' EasyAuth
  • Improved local development experience with .NET Aspire orchestration

The end result is a modern, containerized application that's both easier to maintain and more pleasant to use. The addition of dark mode support and theming capabilities are great improvements to the user experience.

Want to Learn more?

To learn more about Azure Container Apps I strongly suggest this repository: Getting Started .NET on Azure Container Apps, it contains many step-by-step tutorials (with videos) to learn how to use Azure Container Apps with .NET.

Have questions about the migration process or want to share your own experiences with FluentUI Blazor? Feel free to reach out to me on @fboucheros.bsky.social or open an issue on the AzUrlShortener GitHub repository. I'd love to hear your thoughts!


References