.NET Framework 4.8 to .NET 8 on a 14 year old insurance app: what actually broke
Contents
Just rolled off a 9 month contract moving an insurer's claims system off .NET Framework. WebForms, WCF, EF6, 380k lines, written by at least four different consultancies judging by the naming conventions. Here's what actually broke, because the Microsoft docs make it sound like a weekend and it is not a weekend mate.
1. WebForms does not exist in .NET 8. Full stop.
There is no upgrade path for .aspx pages. You rewrite them. The only sane way is incremental: put a new ASP.NET Core app in front with YARP as a reverse proxy, move pages one at a time, and everything you haven't moved yet gets proxied to the old site.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
app.MapControllers(); // the pages we've moved
app.MapReverseProxy(); // everything else goes to the old WebForms site
app.Run();
Users never noticed which half they were on. Big bang rewrite of WebForms is how you end up two years in with nothing live and a new CTO asking questions.
2. WCF services
Server side WCF isn't in .NET 8. CoreWCF covers the common bindings and got our basicHttp services across with very few changes. One service using a custom binding we just rewrote as a REST endpoint, it was easier than arguing with it.
3. Config
web.config appSettings became appsettings.json and IConfiguration. As a stopgap the System.Configuration.ConfigurationManager package still works, which let us move code first and fix config later.
4. EF6 stayed EF6 (for now)
EF 6.4 and later runs on modern .NET, so we didn't touch the data layer in the same project. Moving to EF Core is next year's contract. Somebody else's problem, possibly mine again.
5. The ones that actually hurt
- System.Drawing on Linux. Windows only since .NET 6. They generated PDF thumbnails with it. Swapped for SkiaSharp, two weeks including the bit where the thumbnails were slightly different colours and the business noticed.
- BinaryFormatter. Session state was serialised with it. Obsolete, disabled by default in ASP.NET Core, and a security hole anyway. Moved session to JSON in Redis. Every object in session had to be serialisable, and half of them had circular references. Absolute joke.
- A 2009 DLL with no source. Third party rating engine, vendor long gone. We didn't upgrade it. We fenced it off: a tiny .NET Framework 4.8 service on one Windows box, internal API in front, nothing else talks to it. Not everything needs upgrading, it needs fencing off.
The csproj at the end
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CoreWCF.Http" Version="1.5.2" />
<PackageReference Include="EntityFramework" Version="6.5.1" />
<PackageReference Include="Yarp.ReverseProxy" Version="2.1.0" />
</ItemGroup>
</Project>
Numbers
9 months, 2 contractors. Six Windows VMs down to three Linux containers plus the one Windows box for the 2009 DLL. Licensing and hosting saving about £2,100 a month, which pays for the migration in under three years. The Upgrade Assistant was handy for the class libraries and the packages.config to PackageReference bit, and useless for everything that actually mattered.
And yes, IR35 nearly ended the contract halfway through when the client's HR got nervous. That's a different rant. Crack on.
Get the best of #legacy-code-archaeology weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment