.NET 11 RC1 Adds an Agent Layer to Blazor. Here's Where It Fits in a Migration
by DeeDee Walsh, on Sep 26, 2026, 7:25:42 PM
Microsoft's first .NET 11 release candidate is supported for production use as the platform moves toward its Nov. 10 launch. Most RC1 coverage is about C# 15, which RC1 makes the default language version for projects that target .NET 11. For teams moving VB6, PowerBuilder, Delphi or other legacy apps onto .NET, a smaller addition matters more: a new package of Blazor components for building agent interfaces.
This post covers what's in the package, why migrated applications are well placed to use it, and why you should add it after the migration rather than during it.
What shipped
The package is Microsoft.AspNetCore.Components.AI. It includes an initial set of Blazor AI components for streaming chat, rich-text and tool rendering, human approval flows, and typed, shared, and predictive UI state. One caveat up front: the package is a prerelease, experimental package throughout .NET 11. Plan to prototype with it, not ship on it.
The core pieces:
UIAgentwraps anyIChatClientfromMicrosoft.Extensions.AIand turns its streamed output into renderable content blocks.ChatPagegives you a working conversation UI out of the box.- Block types cover server tool calls, client-side actions, and approvals.
FunctionApprovalBlockrepresents a function call that is waiting for user approval. - Remote agents connect through AG-UI. AG-UI is required when a remote server and the Blazor client must exchange frontend tool declarations, backend tool events, approval interrupts, shared-state events, or AG-UI conversation identifiers.
Why migrated apps are a good fit
In a legacy line-of-business app, the business rules usually live inside event handlers. The credit-hold logic sits in cmdCreditHold_Click. It reads text boxes directly and depends on module-level globals. An agent can't call that code. Neither can a test harness, and neither can a new UI.
A deterministic migration pulls those rules out into ordinary C# methods with typed parameters, and that's the shape an agent needs to call something as a tool. The migration work you're already doing is what makes the agent layer possible. Without it, you'd be asking a model to operate a UI it can't see, against logic nobody can isolate.
Migrate first, then add the agent
It's tempting to redesign the application into an agent-driven workspace during the migration. Don't.
Your users have run these screens for twenty years, and on day one they need them to behave the same way. Your test strategy also depends on comparing old and new behavior, which only works if the behavior is supposed to match. Changing the interaction model mid-migration removes both safety nets at once.
The better sequence:
- Migrate faithfully and verify that behavior matches the original.
- Pick the specific workflows where an assistant helps.
- Add the agent layer to those workflows, calling the migrated methods you've already tested.
What it looks like
Here's a migrated method. It's illustrative, but it's the typical shape once logic comes out of a form:
csharp
// Migrated from cmdCreditHold_Click in frmCustomer.frm. // Business rules preserved; UI dependencies removed. public sealed class CustomerService(AppDbContext db) { public async Task<CreditHoldResult> ApplyCreditHoldAsync( string customerId, string reason, CancellationToken ct = default) { // Same validation and state transitions as the VB6 handler, // now callable from a form, a test, or an agent. } }
On the agent server, you expose that method as a tool and mark it as requiring approval. With Microsoft Agent Framework, the server decides which functions require approval, and AG-UI transports the request and decision.
In the Blazor app, you point IChatClient at that agent:
builder.Services.AddHttpClient<IChatClient>(httpClient => new AGUIChatClient(new(httpClient, "https://your-host/agent")));
Then you render the approval step:
@rendermode InteractiveServer @using Microsoft.AspNetCore.Components.AI @using Microsoft.Extensions.AI @implements IDisposable @inject IChatClient ChatClient <ChatPage Agent="agent" Placeholder="Ask about a customer account..."> <MessageListContent> <BlockRenderer TBlock="FunctionApprovalBlock" Context="approval"> <p>The assistant wants to run <code>@approval.ToolName</code>.</p> <button @onclick="approval.Approve">Approve</button> <button @onclick="() => approval.Reject()">Reject</button> </BlockRenderer> </MessageListContent> </ChatPage> @code { private UIAgent agent = default!; protected override void OnInitialized() => agent = new UIAgent(ChatClient); public void Dispose() => agent.Dispose(); }
The conversation pauses until the UI calls Approve or Reject. The model interprets the request and proposes the action. The user approves it. The migrated, tested C# code does the work. The model never touches the business rules.
Predictive state and the Save/Cancel pattern
One feature maps closely onto how legacy users already work. Predictive state lets an app render an agent's proposed state change while the model is still generating it, without replacing the committed state. The user then accepts or rejects the proposal. If generation fails, is canceled, or ends without a decision, the provisional value is automatically rolled back.
That's a Save/Cancel form with the assistant filling in the fields. Users who have clicked Cancel on a VB6 dialog ten thousand times won't need training to understand it.
Where it doesn't fit
High-volume data entry is the clearest case. An experienced clerk tabbing through a keyboard-driven form will outpace a chat window every time, so leave those screens alone.
The better candidates are tasks that span several screens today: researching an account across four tabs, assembling an exception report, or walking a newer employee through a rarely used process.
Timing
.NET 10 is an LTS release supported through November 14, 2028, while .NET 11 is an STS release. Combined with the experimental status of the AI components, the practical plan is:
- Run production migrations on .NET 10 today.
- Prototype the agent layer on .NET 11 in parallel, against methods you've already migrated.
- Expect the API to change before it stabilizes.
For a walkthrough of the migration half of this story, see our VELO for VB6 webinar.


