diff --git a/aspnetcore/migration/100-to-110.md b/aspnetcore/migration/100-to-110.md index def746553c4e..9c74c492e074 100644 --- a/aspnetcore/migration/100-to-110.md +++ b/aspnetcore/migration/100-to-110.md @@ -1,7 +1,8 @@ --- title: Migrate from ASP.NET Core in .NET 10 to ASP.NET Core in .NET 11 +ai-usage: ai-assisted description: Learn how to migrate an ASP.NET Core in .NET 10 to ASP.NET Core in .NET 11. -ms.date: 07/15/2026 +ms.date: 10/19/2026 uid: migration/100-to-110 --- # Migrate from ASP.NET Core in .NET 10 to ASP.NET Core in .NET 11 @@ -75,6 +76,10 @@ In the project file, update each [`Microsoft.AspNetCore.*`](https://www.nuget.or [!INCLUDE[](~/migration/100-to-110/includes/security.md)] +## ASP.NET Core MVC + +[!INCLUDE[](~/migration/100-to-110/includes/mvc.md)] + ## Breaking changes Use the articles in [Breaking changes in .NET](/dotnet/core/compatibility/breaking-changes) to find breaking changes that might apply when upgrading an app to a newer version of .NET. diff --git a/aspnetcore/migration/100-to-110/includes/mvc.md b/aspnetcore/migration/100-to-110/includes/mvc.md new file mode 100644 index 000000000000..55ff768eaae6 --- /dev/null +++ b/aspnetcore/migration/100-to-110/includes/mvc.md @@ -0,0 +1,73 @@ +### Upgrading F# MVC applications from .NET 10 to .NET 11 + +Newly generated .NET 11 F# MVC projects already include build- and publish-time Razor compilation and view assembly registration. The following steps apply when migrating an existing F# MVC application from .NET 10 or earlier. + +F# MVC projects generated by earlier templates use the [`Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation` NuGet package](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation) and call . Razor runtime compilation is obsolete in .NET 10 or later ([breaking change announcement](/aspnet/core/breaking-changes/10/razor-runtime-compilation-obsolete)). Unlike C# MVC projects, F# projects can't use the Razor source generator directly. Removing runtime compilation without configuring compilation causes the app to build successfully but fail at runtime when a view is requested with an . + +To upgrade an existing F# MVC project: + +1. Remove the `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation` package reference from the project file (`.fsproj`). +1. In `Program.fs`, remove the call to `AddRazorRuntimeCompilation`. +1. Configure Razor compilation in the project file: + + ```xml + + false + true + true + + ``` + +1. Add `MvcBuilderExtensions.fs` to the project file before `Program.fs`, as F# compilation order is significant: + + ```xml + + + + + + ``` + +1. Add `MvcBuilderExtensions.fs`. The namespace must match the application's root namespace (for example, `Company.WebApplication1`): + + ```fsharp + namespace Company.WebApplication1 + + open System + open System.IO + open System.Reflection + open System.Runtime.CompilerServices + open System.Runtime.Loader + open Microsoft.AspNetCore.Mvc.ApplicationParts + open Microsoft.Extensions.DependencyInjection + + [] + type MvcBuilderExtensions = + [] + static member AddCompiledRazorViews(builder: IMvcBuilder) = + let applicationAssembly = Assembly.GetExecutingAssembly() + let viewsAssemblyName = $"{applicationAssembly.GetName().Name}.Views" + let viewsAssemblyPath = + Path.Combine(AppContext.BaseDirectory, $"{viewsAssemblyName}.dll") + let loadContext = + AssemblyLoadContext.GetLoadContext(applicationAssembly) + + let viewsAssembly = + if File.Exists(viewsAssemblyPath) then + loadContext.LoadFromAssemblyPath(viewsAssemblyPath) + else + loadContext.LoadFromAssemblyName(AssemblyName(viewsAssemblyName)) + + builder.PartManager.ApplicationParts.Add( + CompiledRazorAssemblyPart(viewsAssembly)) + builder + ``` + +1. Register the compiled views in `Program.fs`: + + ```fsharp + .AddControllersWithViews() + .AddCompiledRazorViews() + ``` + +This configuration compiles Razor views during build and publish and registers the resulting views assembly with MVC. It avoids the obsolete runtime compilation dependency and allows view discovery at runtime.