Pre-Migration Checklist for Moving from .NET Framework to .NET
· Go Komura · .NET, .NET Framework, C#, Modernization, Windows Development, Migration
Download the Excel checklist with Japanese and English sheets
Change TargetFramework in the .csproj to net10.0, update a few NuGet packages, and once the build passes, you are done.
…If that were the migration, life would be pretty peaceful. In reality, it usually is not.
.NET Framework codebases are full of dormant assumptions you normally never think about: System.Web, WCF, Web Forms, old packages.config files, web.config.install.xdt, native DLLs, COM / ActiveX, third-party controls that only work at design time, implicit x86 assumptions, designer-dependent ResX, old serializers, and more.
So what really matters in a .NET Framework to .NET migration is the inventory work before you start implementing. If you can break the issues down before starting, the migration stops being “a big gamble” and becomes “a list of items to knock down in order.”
This article summarizes what you should verify before migrating an existing .NET Framework 4.x line-of-business application to current .NET. The main targets are around here:
- Class libraries
- Console applications
- Windows services
- WinForms / WPF
- ASP.NET Framework (MVC / Web API / Web Forms)
- Applications that use WCF
- Applications that use EF6
This was written as of 2026-03-15. Support windows and official tooling recommendations change, so if you are reading this much later, check the official information as well.
1. The Conclusion First
First, the conclusions that are hard to get wrong.
- Clean up the .NET Framework side before migrating. Microsoft’s official guide also recommends upgrading to .NET Framework 4.7.2 or later before porting, and completing
PackageReferenceconversion, SDK-style conversion, and dependency updates first. - Difficulty is determined by app model, not by code volume. Class libraries and console apps are relatively light; ASP.NET Framework, Web Forms, WCF servers, and WF tend to be heavy.
- WinForms / WPF can migrate to .NET but remain Windows-only. Misunderstand this and you step on the classic landmine of migrating only to find the app will not run in a Linux container.
- ASP.NET Framework → ASP.NET Core is effectively an architecture migration. Small apps can sometimes go in one shot, but for large production systems it is safer to plan on an incremental migration.
- WCF and EF6 can sometimes be decoupled from the runtime migration. WCF clients have supported packages for .NET, and EF6 can be migrated to EF Core separately after the move to modern .NET.
- On the other hand, AppDomain creation, .NET Remoting, CAS, COM+, Workflow Foundation, and BinaryFormatter dependencies are red lights. Find them early, or the effort explodes later.
packages.config/install.ps1/XDT/contentassets / native DLLs / COM / ActiveX / x86 assumptions tend to fail at runtime or design time even when the build passes, so flush them out before starting.- As of 2026-03, .NET 10 is the LTS. For new migrations, it is natural to target the current LTS as the landing point.
- A migration without tests, measurements, and a rollback plan is dangerous. Migration is less an implementation task than a job of making assumptions visible, one at a time.
2. First Decide Whether You Should Migrate Right Now at All
The first thing to decide is not “how to migrate” but whether this app really should be migrated right now.
Leave this vague and you tend to end up with a migration that is technically correct but too heavy for the business — or the opposite: postponing far too long when migration is clearly the right call.
2.1 Staying on .NET Framework Is a Perfectly Valid Decision
.NET Framework 4.8.1 continues to be supported as long as it runs on a supported Windows. In other words, it is not as simple as “if you do not move everything to modern .NET right now, you are immediately at risk.”
However, staying has clear constraints.
- You cannot escape being Windows-only
- You keep carrying ASP.NET Web Forms and old server stacks
- It is harder to benefit from new .NET performance improvements, language features, and the ecosystem
- You drift away from the modern assumptions of cloud, containers, and CI/CD
Conversely, if dependencies like the following are strong, it is rational to consolidate on .NET Framework 4.8.1 for stable operation for now, while planning the replacement on a separate track.
- A large stock of Web Forms screens
- Strict WCF server compatibility must be preserved
- Deep Workflow Foundation or COM+ dependencies
- Third-party design-time components do not support modern .NET
- The business does not allow major specification changes
2.2 What Changes with Each Option
| Option | What gets better | What remains / what you give up | Good fit |
|---|---|---|---|
| Stay on .NET Framework 4.8.1 | Easy to keep existing assets intact and operate stably | Windows-only, old app models, limits on modernization | Strong legacy dependencies; the business priority is stable operations for now |
| Migrate to modern .NET but stay on Windows | Runtime and toolchain modernized. Big gains in performance, developer experience, SDK style | Windows API dependencies remain. Not cross-platform | WinForms / WPF, Windows services, business apps using Windows APIs |
| Migrate to modern .NET with Linux / containers / cloud in future scope | More freedom in deployment targets. Easier to modernize the operations model | Windows-only APIs and app models must be peeled off first | You want to shift the server side toward the cloud and refresh infrastructure too |
What matters is deciding not whether you want to migrate but where you want to land after the migration — first.
3. Four Policies to Decide Up Front
3.1 The Target .NET Version
At the time of writing, under Microsoft’s support policy, .NET 10 is the LTS. Meanwhile, .NET 8 LTS and .NET 9 STS are both scheduled to reach end of support on 2026-11-10.
So if you are now starting a fresh migration off .NET Framework, barring exceptional circumstances, landing on the current LTS is the natural choice.
The practical reasoning here is simple.
- For a small migration you want done quickly, land directly on the current LTS
- For a core system intended for long-term operation, still treat the current LTS as the baseline
- “We want the previous LTS because of an existing library” is a legitimate reason, but judge it by checking the actual maintenance end date
3.2 Stay Windows-Only, or Aim for Cross-Platform Later?
This decision dramatically changes which issues you need to look at.
- If you stay Windows-only, you can take the pragmatic route of modernizing the runtime first, using WPF / WinForms and the Windows Compatibility Pack.
- If you are aiming for Linux / containerization later, you need to inventory Windows-bound APIs early:
System.Drawing.Common, the registry, WMI, EventLog, Windows services, COM, Office Interop, and so on.
Start migrating without deciding this, and midway through, the conversation gets twisted: “Was Windows-only fine after all?” “No wait, we wanted to run in containers.”
3.3 One Shot or Incremental?
There are broadly three migration shapes.
- Near in-place, all-at-once migration
- Side-by-side migration running old and new in parallel
- Incremental migration, moving over route by route or library by library
Especially for ASP.NET Framework apps, Microsoft’s guidance explicitly recommends incremental migration. If you cannot stop production, have many features, and have many surrounding dependencies, it is less strained to design for incremental migration from the start.
3.4 What to Exclude from This Migration
Migrations tend to fail because too much gets piled on.
For example, doing all of these at once tends to get heavy:
- .NET Framework → .NET
- ASP.NET Framework → ASP.NET Core
- EF6 → EF Core
- Windows servers → Linux containers
- Changing the authentication infrastructure
- Changing the logging / monitoring infrastructure
- Migrating the database
Of course, all of them may eventually be necessary. But whether they must be done at the same time is a separate question.
In reality, separating things like this works better:
- First modernize the runtime and project structure
- Then move the app model
- Finally update the ORM, authentication, cloud, and monitoring
4. The Foundation to Prepare Before Starting
Microsoft’s pre-porting guide is quite practical. In essence: before migrating, bring your current .NET Framework projects up to a modern entry point.
4.1 Upgrade to .NET Framework 4.7.2 or Later
The official guide recommends targeting .NET Framework 4.7.2 or later before porting. The reason is that even when .NET Standard does not carry an existing API as is, it becomes easier to move toward newer API alternatives.
In practice, it is clearer to use 4.8.1 as the baseline if possible.
- Straightforward from a support standpoint
- Easy to treat as the final stable point on the .NET Framework side
- Makes the policy of “first clean up on the current Framework side” easy to establish
What changes if you do this first
- Handling of
.NET Standard 2.0shared libraries stabilizes more easily - Noise originating from the old runtime is reduced up front
- It becomes easier to tell whether a compatibility issue is caused by “the Framework being old” or by “the move to modern .NET”
4.2 Move to PackageReference
The pre-porting guide recommends converting references to the PackageReference format.
Doing this first significantly improves visibility into dependency management.
What changes with PackageReference
- Package references are consolidated into the
csproj - Transitive dependencies become easier to see
- The restore assumptions line up with the modern .NET side
- Better compatibility with the CLI / CI
However, there are landmines here.
Typical landmines
The official NuGet documentation explicitly lists these constraints for migrating from packages.config to PackageReference:
- Visual Studio’s built-in migration cannot be used for ASP.NET projects
- Packages that depend on
install.ps1/uninstall.ps1may not work as expected - Assets in the
contentfolder may be ignored - XDT transforms such as
web.config.install.xdtare not applied - Packages with old assembly layouts directly under
libmay not resolve well
In other words, do not think of it as merely changing the package format.
Classic ASP.NET in particular had a strong culture of rewriting web.config at NuGet package install time, so implicit assumptions surface easily during migration.
4.3 Move to SDK-Style Projects
The pre-porting guide also recommends converting to the SDK-style project format.
This pays off substantially.
What changes with SDK style
- The
csprojbecomes dramatically more concise - Plays well with
PackageReference - Multi-targeting becomes easy
- Easier to center CI/CD on
dotnet build/dotnet test/dotnet publish - The configuration approaches the modern .NET side, reducing the diff in the later phase
Put the other way around: jumping straight to modern .NET with old csproj files and old NuGet management produces too large a diff.
4.4 Update Dependencies First
This too follows the official guide: move dependencies to the latest available versions, and where possible to .NET Standard-compatible versions.
Why do this first
- You find out early whether “this package works on modern .NET”
- Prevents old dependencies from becoming noise
- Makes it easier to convert shared libraries to
netstandard2.0 - Lets the later migration work focus on “porting the code”
4.5 Check the Assumptions of the Official Tooling Too
As of 2026-03, the center of gravity of Microsoft’s guidance has shifted toward GitHub Copilot app modernization. Rather than assuming only the traditional migration assistant tools, it matches practice better to view it as an end-to-end support flow covering assessment, planning, code fixes, and validation.
However, the current documentation assumes Visual Studio 2026 or a supported Visual Studio 2022 line, GitHub Copilot, and C# code.
Why this check is needed
- It changes what you can expect from the official tooling
- You can align the team’s assumptions about IDEs / build agents / extensions
- You can make the call to not over-rely on automation for VB.NET solutions
Codebases with VB.NET mixed in are not rare. So it is worth confirming, at the very start, “how far the latest official tooling will actually help.”
5. Estimating Difficulty per Project Type
Migration tends to be discussed as one lump — “.NET Framework to .NET” — but in reality each project type is a different game.
5.1 A Rough Sense of Difficulty
| Type | Difficulty | Main issues |
|---|---|---|
| Class library | Low to medium | API compatibility, dependencies, target splitting |
| Console / batch / some Windows services | Low to medium | Distribution method, native dependencies, configuration |
| WinForms / WPF | Medium | Remains Windows-only; designer, third-party UI, BinaryFormatter surroundings |
| ASP.NET MVC / Web API | Medium to high | App model migration to ASP.NET Core, authentication, session, configuration, DI |
| ASP.NET Web Forms | High | Large gap in page model; assume UI layer replacement |
| WCF client | Medium | Package replacement, contracts, configuration |
| WCF server | High | CoreWCF, or redesign as gRPC / HTTP API |
| EF6 → EF Core done simultaneously | High | The ORM is a different beast; behavioral differences; migration history |
5.2 For Class Libraries, the Key Is How You Cut the “Shared Boundary”
Class libraries are relatively easy to move. But only when the library is genuinely separated like a library.
Dependencies like the following raise the difficulty:
- Touching
System.Web - Reading
HttpContext.Currentdirectly - Exposing WPF / WinForms types in the public API
- Leaning heavily on Windows APIs such as the registry, WMI, EventLog
- Depending on
AppDomainor Remoting
A useful framing: if you can extract pure business logic, it is light; if the library has swallowed the app model, it is heavy.
5.3 WinForms / WPF Migrate Easily, but Stay Windows-Only
WinForms and WPF can be migrated to .NET. However, both remain Windows-only frameworks.
Getting expectations wrong here is dangerous.
- What improves
- You get the modern .NET runtime, language, and SDK style
- CI/CD and package management can be brought up to date
- Some performance and maintainability improvements come along
- What does not change
- It is still Windows-only
- Compatibility issues with UI controls and design-time components remain
- ActiveX / COM / native DLL problems do not go away
Also, WinForms / WPF can require a BinaryFormatter impact review. Especially when custom types are involved in the clipboard, drag & drop, ResX, or design-time serialization, the issue tends to surface when you raise the target to .NET 9 or later.
5.4 ASP.NET Framework Is an “App Model Migration,” Not a “Runtime Migration”
Migrating from ASP.NET Framework to ASP.NET Core is explicitly described as non-trivial in Microsoft’s guidance. Not merely because API names change, but because the underlying architecture is different.
The differences tend to show up around here:
- Hosting model
- Middleware pipeline
- Request processing model
- Session / Cache
- Authentication / Authorization
- Configuration
- Dependency Injection
- Logging / Monitoring
For an ASP.NET Framework app, the things to check first are around here:
- Which routes / endpoints can be moved first
- Whether
System.Webdependencies can be peeled out of shared libraries - How to align authentication / session / exception handling / logging
- Whether to migrate incrementally without stopping production
For large apps in particular, it is more realistic to assume incremental migration from the start.
5.5 For Web Forms, Start with “Decomposing Responsibilities,” Not “Migrating Assets”
Web Forms is not the same app model as ASP.NET Core. So for estimation purposes, it is safer not to assume the screen assets can be carried over as is.
In practice, the usual entry point is this decomposition:
- Separate screen logic from business logic
- Break apart the responsibilities buried in
Page/UserControl/ViewState - Move business logic and data access out into shared libraries
- Rebuild the UI on a different model: Razor Pages / MVC / Blazor, etc.
In other words, for Web Forms projects, whether there is a responsibility-decomposition plan matters more than the runtime migration itself.
5.6 Treat WCF Clients and WCF Servers Separately
Do not lump these together.
WCF clients
The WCF Client has supported NuGet packages for modern .NET. So if you only call WCF, the work can be lighter than it looks.
WCF servers
Hosting WCF services, on the other hand, is a different story. Microsoft’s guidance presents two broad modernization paths:
- Use CoreWCF to preserve compatibility with existing clients
- Move to modern RPC / HTTP-based stacks such as gRPC
Note that CoreWCF is a subset — it does not bring over all of WCF as is. It is suited to preserving compatibility with existing clients, but code changes and testing are a given.
6. Flush Out Technologies That Do Not Work on .NET, or Get Stuck Easily
This is something you absolutely want to do before starting. Microsoft maintains a list of technologies available on .NET Framework that are unavailable on .NET 6+.
6.1 Technologies That Tend to Be Red Lights
| Technology | Status on .NET | How to think about it |
|---|---|---|
AppDomain creation such as AppDomain.CreateDomain |
Unsupported | Think of isolation via separate processes / containers / AssemblyLoadContext |
| .NET Remoting | Unsupported | Redesign around IPC, HTTP, gRPC, sockets, pipes |
| CAS / Security Transparency | Unsupported as a security boundary | Think in terms of OS / container / privilege separation |
System.EnterpriseServices (COM+) |
Unsupported | Isolate and replace COM+-based designs |
| Workflow Foundation | Unsupported | Estimate separately, including alternatives such as CoreWF |
| WCF server | Not available as is in the box | Choose CoreWCF or gRPC |
| BinaryFormatter | On .NET 9+ the implementation always throws | Migrate serializers; audit ResX / clipboard / drag & drop |
6.2 AppDomain: “Some APIs Remain, but Creation Is a Different Matter”
The AppDomain area is a bit tricky.
Some of the API surface remains on .NET, but the usage pattern of creating a new AppDomain for isolation is not supported.
So if you used AppDomains for the following purposes, a redesign is needed:
- Plugin isolation
- Unloading dynamically loaded code
- Isolating partially trusted code
- Temporary separation of execution environments
What you should look at before migrating is not just whether the word AppDomain appears, but what the AppDomain was being used for.
6.3 Remoting Is “Deeper Than It Looks”
Remoting itself, obviously — but asynchronous delegate calls like BeginInvoke() / EndInvoke() on delegates can also fall into the affected area. This is not Remoting per se, but it is unsupported on modern .NET, so it needs to be flushed out before migrating.
So when searching, it is safer to look at this set together:
System.Runtime.RemotingMarshalByRefObjectRealProxyBeginInvoke(/EndInvoke(
6.4 BinaryFormatter Suddenly Comes to the Fore Depending on the Target Version
The older the codebase, the more likely BinaryFormatter is being used “without awareness.”
- Persisted data
- Caches
- Session storage
- Plugin state
- Clipboard / drag & drop
- ResX
- WinForms / WPF designer surroundings
On .NET 9 and later, BinaryFormatter’s implementation is not included in the runtime and the API always throws PlatformNotSupportedException.
So this is not a “think about it later” item — it is an audit item the moment you decide the target version.
6.5 Search Terms to Grep for First
Before starting, just running searches over the whole solution with the following terms changes the picture considerably.
System.Web
HttpContext.Current
System.Runtime.Remoting
MarshalByRefObject
AppDomain
BinaryFormatter
ServiceHost
ChannelFactory
System.EnterpriseServices
Workflow
packages.config
web.config.install.xdt
install.ps1
DllImport
AxInterop
Microsoft.Office.Interop
Finding even one of these does not mean instant failure. It is a map for knowing which parts can migrate on the standard route and which become a separate track.
7. Decide How Much Windows-Only Dependency to Accept
A common misunderstanding in migrations is “once we are on .NET, we are cross-platform.” There is no such magic. If the app is deeply tied to Windows, it remains Windows-only after the migration, plainly.
7.1 Migrating While Staying Windows-Only Is Entirely Realistic
Microsoft provides the Windows Compatibility Pack, a way to use many Windows-oriented APIs — the registry, WMI, EventLog, Windows services, Directory Services, and so on — from modern .NET.
Its existence matters a lot in practice.
- We want to move to modern .NET first
- But we are not leaving Windows for now
- So we want to accept the Windows API dependencies for the time being
For teams in that situation, it is a strong option.
The first goal of a migration does not have to be going cross-platform.
7.2 But Windows-Only APIs Are Also “Debt That Bites Later”
The Windows Compatibility Pack existing does not make everything safe.
- You want to run in Linux containers
- You want to run on Kubernetes
- You want macOS / Linux developers running the same build
- You want to reduce Windows VMs in the cloud someday
If you have goals like these, it is better to make the Windows API dependencies visible now.
7.3 System.Drawing.Common Is Especially Often Misunderstood
System.Drawing.Common is a Windows-only library on .NET 6 and later.
If you have code using it for image processing or text rendering, you first need to decide which way to go.
- Keep operating on Windows?
- Or want it running on Linux / macOS in the future?
In the former case, leaving it as is for now can be fine. In the latter, a replacement — SkiaSharp, ImageSharp, etc. — needs to be in the migration plan from the start.
7.4 Typical Smells That Indicate Windows Lock-In
When references or APIs like the following are present, it is safer to estimate on the assumption of “migrating while staying Windows-only, at least at first.”
Microsoft.Win32.RegistrySystem.ManagementSystem.Diagnostics.EventLogSystem.ServiceProcessSystem.DirectoryServicesSystem.DrawingDllImport/ P/Invoke- COM references
AxInterop.*Microsoft.Office.Interop.*
8. How You Carve Out Shared Libraries Changes the Difficulty
For larger solutions, it is no exaggeration to say the success of the migration is determined by how you cut the shared libraries.
8.1 Classify First
Libraries are easiest to organize when split into three broad kinds.
- Pure business logic / domain logic
- Middle layers with some app model dependency
- Layers tightly coupled to UI / Web / Windows APIs
Of these, the first to migrate should be kind 1.
- Calculations
- Rule evaluation
- DTOs / contracts
- Domain services
- Simple data transformations
If you can extract this cleanly, the difficulty drops sharply.
8.2 netstandard2.0 Is Still a Valid Bridge
Per Microsoft’s guidance, for a shared library that must also coexist with the .NET Framework side, the baseline is to consider .NET Standard 2.0 first.
Two points matter here.
- .NET Framework does not support
.NET Standard 2.1 - If you want a shared library referenced from both old and new, 2.0 tends to be the practical answer
8.3 What Changes with netstandard2.0
| Policy | What changes | Good fit | Caveats |
|---|---|---|---|
Convert to netstandard2.0 |
Easy to reference from both old and new | Pure business logic, common contracts, utilities | App-model-specific APIs cannot live here |
Multi-target (e.g. net48;net10.0) |
Keep common code while holding per-environment differences | Libraries with a few environment differences | More conditional compilation and build management |
Go straight to net10.0-only |
Cleanest in the long run | New layers that do not need old/new coexistence | Cannot be referenced from .NET Framework |
8.4 Compatibility Mode Is Not a Cure-All
.NET Standard 2.0 has a compatibility mode that allows referencing .NET Framework libraries. However, this is not magic that makes everything work transparently.
For example, libraries that assume app-model-specific APIs like WPF are plainly difficult. In other words, even when you say “shared library,” it is important to narrow it down to the responsibilities that can truly be shared.
8.5 For ASP.NET-Related Libraries, the Battle Is Whether You Can Peel Off System.Web
When incrementally migrating ASP.NET Framework, having shared libraries hang directly off HttpContext.Current or System.Web is quite painful.
The basic strategies at that point are one of these:
- Push the
System.Webdependency outside the interface - Change the code to receive
HttpContext-derived information as DTOs - Use adapters during the transition period
- If that still does not work, peel it off gradually with multi-targeting
8.6 Raise Libraries Leaf-First
The ASP.NET incremental migration guide explicitly says to upgrade supporting libraries postorder depth-first — that is, from the leaves up.
This is quite effective for general solutions too, not just web.
- Because dependencies are upgraded first, the upper layers become easier to see through
- Compatibility issues are easier to localize
- Testing per library becomes easier
9. Take Inventory of NuGet / External Dependencies / Third-Party Components
Do this sloppily and you suffer the worst pain in the second half of the migration.
9.1 Dependencies Are Easier to Organize in 4 Categories
- Public NuGet packages
- In-house private packages / internal libraries
- Local DLL references
- COM / ActiveX / native DLLs / SDKs
Looking only at category 1 is not enough. The really dangerous ones are 3 and 4.
9.2 What to Verify for Each Dependency
For each dependency, verify at least this much:
- Does it target modern .NET?
- Does it support
PackageReference? - Is it fine with SDK-style projects?
- Any x86 / x64 / ARM64 constraints?
- Does it depend on design-time tooling or Visual Studio extensions?
- Does it assume install scripts / config transforms?
- Is it still supported?
9.3 Estimate Third-Party UI / Reporting / Design-Time Components Separately
For WinForms / WPF / ASP.NET migrations, this area matters a lot.
- Grids
- Reporting engines
- PDF output components
- Charting components
- Designer-integrated UI libraries
- ActiveX wrappers
These involve design-time support, not just the runtime. If your migration estimate only checks “does it compile,” you will plainly miss these.
9.4 Always Check Native DLLs and Bitness
Even if things seemed to run as AnyCPU in the .NET Framework era, in reality they may depend on things like:
- COM fixed to
x86 - 32-bit-only ActiveX
- A specific version of the VC++ Runtime
- Signed native DLLs
These are not problems that suddenly sprouted with the move to modern .NET — constraints that were always there simply surface. Which is exactly why it is worth making them visible before the migration.
10. Treat EF6, Serializers, and the Data Layer as Separate Problems
The runtime migration and the redesign of data access and serialization work out better when treated as separate problems wherever possible.
10.1 EF6 → EF Core Is Not a Direct Upgrade
Microsoft’s EF guidance also states that EF Core is a total rewrite of EF6 and there is no direct upgrade path.
So for apps using EF6, this order is realistic:
- First move to modern .NET
- Keep EF6 if needed and run the app
- Then migrate to EF Core as a separate project
Do not combine the runtime migration with the ORM migration. That alone lowers the difficulty considerably.
10.2 What Changes if You Keep EF6
- Upsides
- The data access layer diff can be deferred
- You can focus on migrating business logic and the app model
- “EF Core behavioral differences” do not get mixed in
- Caveats
- For new development, EF Core is the main line
- EF6 Designer / EDMX usage patterns have separate constraints
10.3 For EDMX-Based EF6, Look All the Way to “Design Time”
The EF6 documentation states that the EF Designer is not directly supported in .NET / .NET Standard projects or SDK-style .NET Framework projects.
For EDMX-based apps, you need to consider these three points separately:
- Does it run at runtime?
- Can the Designer be used?
- How will the generated code be handled?
If you use EDMX heavily, it is safer to put this in the estimate from the start.
10.4 BinaryFormatter and Custom Serialization Easily Become “Hidden Dependencies”
Serializers are easy to miss with code search alone.
- Persistence formats
- Messaging
- Caches
- Old WCF / SOAP contracts
- ResX
- Clipboard / drag & drop
This area also involves data compatibility. That is, you need to verify not just “does it build” but can it still read the old data.
11. Include Configuration, Distribution, Operations, and CI/CD in the Migration Scope
The migration target is not just source code.
11.1 Configuration Files
On the .NET Framework side, quite a lot can be riding in app.config / web.config.
- Connection strings
- Custom config sections
- WCF endpoint configuration
- Binding redirects
- Diagnostics
- Various ASP.NET settings
- The results of transforms applied at package install time
On the modern .NET side, how configuration is held and loaded changes in places. So “configuration files later” is dangerous.
The first thing to do is an inventory of the configuration.
- What lives in the configuration files
- Which entries are required at app startup
- Which are per-environment differences
- Which were auto-injected by NuGet or installers
11.2 Distribution Method
Look at the distribution shape before starting too.
- Hosted under IIS?
- A Windows service?
- A Scheduled Task?
- ClickOnce / MSI / a custom installer?
- On-premises servers assumed?
- Is self-contained or framework-dependent the better fit?
Even if the executable itself migrates, you get stuck at the end if the distribution and startup machinery still assumes the old world.
11.3 Logging, Monitoring, and Operational Procedures
The operations side is easy to overlook as well.
- Is the Windows Event Log assumed?
- Are Performance Counters being watched?
- WMI-based monitoring?
- Are service accounts and permissions fixed?
- Do logs assume local file output?
“The code runs after the migration, but operations cannot function” happens, plainly.
11.4 CI/CD and Build Agents
Before migrating, also check:
- Can the required .NET SDK be installed on the build agents?
- What to do with pipelines that assume
nuget.exe/msbuild.exe - Will you move to the
dotnetCLI? - How to update the test, coverage, and publish jobs
- Are in-house templates or reusable pipelines assuming the old formats?
“It works on my machine but CI dies” is a migration classic.
12. A Realistic Way to Run the Migration
Given everything above, a realistic approach usually settles into roughly this shape.
12.1 First, Put the Current Framework Side in Order
- Move to .NET Framework 4.7.2 or later, ideally 4.8.1
- Upgrade dependencies
- Review
packages.config - Move to
PackageReferenceand SDK style where possible - Confirm the current app genuinely works in that state
Just doing this reduces the diff in the later phase considerably.
12.2 Rescue the Shared Libraries First
Next, move business logic and common contracts toward netstandard2.0 or multi-targeting.
The order of upgrading is, as a rule, leaf-first.
12.3 For the Application Itself, Vary the Strategy per App Model
- Class libraries / console / some services Relatively straightforward
- WinForms / WPF Modernize while staying Windows-only
- ASP.NET MVC / Web API All at once if small; incremental if heavy
- Web Forms Assume screen replacement; move shared logic out first
- WCF servers Decide first: stay with CoreWCF or redesign with gRPC
12.4 Stick to “Not Everything at Once”
The combinations to particularly avoid:
- Runtime migration + full ORM swap
- Runtime migration + authentication infrastructure change
- Runtime migration + full cloud migration
- Runtime migration + monitoring infrastructure change
- Runtime migration + UI framework refresh
Even if all of them are needed, not stacking them in the same sprint usually works out better.
12.5 Take Tests and Baselines Before Moving
At minimum, you want this much in place before moving:
- Unit tests
- Integration tests for the main business flows
- Snapshot-style verification of representative screens / APIs
- A performance baseline
- A way to check the main logs
- A rollback procedure
Proceeding in a state where you cannot identify “what broke” after the migration is quite dangerous.
13. Pre-Start Checklist
Here it is in a form you can paste straight into your project management tool.
13.1 Policy
- You can state in one sentence why you are migrating
- The landing point is decided: Windows-only modern .NET or future cross-platform
- The target .NET version is decided
- What is excluded from this scope (EF Core conversion, auth refresh, full cloud migration, etc.) is decided
13.2 Preparing the Current .NET Framework Side
- Moved to .NET Framework 4.7.2 or later, ideally 4.8.1
- Upgraded dependencies toward the latest
- Checked for
packages.config - Verified feasibility of converting to
PackageReference - Verified feasibility of converting to SDK style
- The current app builds, starts, and passes tests in that state
13.3 App Types and Technology Choices
- Split difficulty by type: class library / desktop / web / WCF, etc.
- Understood that WinForms / WPF remain Windows-only
- Understood that ASP.NET Framework means an app model migration to ASP.NET Core
- Included Web Forms UI layer replacement in the estimate
- Evaluated WCF clients and servers separately
13.4 Unsupported Technologies / APIs Requiring Attention
- Flushed out
AppDomaindependencies - Flushed out Remoting /
MarshalByRefObject/BeginInvoke/EndInvoke - Flushed out CAS / Security Transparency / COM+ / WF
- Flushed out BinaryFormatter dependencies
- Flushed out
System.Webdependencies
13.5 Windows-Only Dependencies
- Flushed out use of the registry, WMI, EventLog, Windows services, Directory Services
- Flushed out use of
System.Drawing.Common - Flushed out COM / ActiveX / Office Interop / P/Invoke / native DLLs
- Verified x86 / x64 / ARM64 constraints
13.6 Shared Libraries and Data Access
- Classified shared libraries into business logic / app-model-coupled layers
- Flushed out what can be converted to
netstandard2.0 - Flushed out libraries that need multi-targeting
- Decided whether the runtime can move first while keeping EF6
- Verified EDMX / Designer dependencies
13.7 Operations and Build
- Took inventory of the configuration files
- Verified the distribution method (IIS / service / MSI / ClickOnce, etc.)
- Verified logging / monitoring / permissions / execution account assumptions
- Verified whether CI/CD and build agents need updating
- Created a rollback procedure
14. Summary
What matters in migrating from .NET Framework to .NET is not “which command to migrate with” but seeing, before you start, what carries over as is and what is a separate problem.
Narrowed to the essentials, it is these six points:
- Clean up the .NET Framework side before migrating
- Split difficulty by app model
- Flush out the unusable technologies first
- Decide how much Windows-only dependency to accept
- Decide how to carve out the shared libraries
- Do not pile on ORM, authentication, and cloud migrations at the same time
The accuracy of the estimate changes dramatically in the first week of a migration. Put another way, if you can sort out the issues in that week, the second half can be steered fairly close to ordinary development.
“Let’s just try changing it to net10.0” is not bad as exploration.
But as a production migration, there are things to look at before that. What this article organized is exactly that.
15. References
- Prerequisites to porting code
- Overview of porting from .NET Framework to .NET
- .NET Framework technologies unavailable on .NET 6+
- What is GitHub Copilot app modernization
- Install GitHub Copilot app modernization
- Official .NET support policy
- .NET Framework official support policy
- Use tooling to migrate ASP.NET Framework to ASP.NET Core
- Migrate from ASP.NET Framework to ASP.NET Core
- Get started with incremental ASP.NET to ASP.NET Core migration
- Use the Windows Compatibility Pack to port code to .NET
- .NET Standard
- Cross-platform targeting for .NET libraries
- Migrate from packages.config to PackageReference
- PackageReference in project files
- BinaryFormatter migration guide
- BinaryFormatter migration guide for Windows Forms applications
- WCF Client Support Policy
- CoreWCF Support Policy
- Why migrate WCF to ASP.NET Core gRPC
- Port from EF6 to EF Core
- What’s new in EF6
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Windows App Outsourcing and Contract Development: What to Sort Out Before You Ask
Before commissioning Windows app outsourcing or contract development, here is how to sort out existing software modification, device inte...
Using Algebraic Data Types in .NET Framework / .NET — Designing States and Results with Types
How to use algebraic data types — especially sum types and discriminated unions — in .NET Framework and .NET, and what you gain: F#, C# c...
Serial Communication App Pitfalls - Through Reconnection and Log Design
The serial communication app pitfalls you want to avoid in device integration and instrument control, organized from a practical perspect...
Calling a C# Native AOT DLL from C/C++
How to publish a C# class library as a native DLL with Native AOT and call UnmanagedCallersOnly entry points from C/C++ — when this setup...
Why Use the .NET Generic Host and BackgroundService in Desktop Apps
How to use the Generic Host and BackgroundService to organize startup, periodic processing, shutdown, logging, configuration, and DI in W...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
Where This Topic Connects
This article connects naturally to the following service pages.
Legacy Asset Reuse & Migration Support
This is about taking stock of existing assets involving .NET Framework, Web Forms, WCF, COM / ActiveX, and old NuGet workflows, so it fits well as a legacy asset migration consultation topic.
Technical Consulting & Design Review
If you want to sort out the migration scope, how to slice an incremental migration, and how much Windows-only dependency to accept before starting, this topic works well as a technical consulting / design review engagement.
Author Profile
Profile page for the article author.
Go Komura
Representative of KomuraSoft LLC
Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.
Public links