Skip to content

warpdriv/net-migration-framework

Repository files navigation

.NET 4.8 → .NET 10 Razor Pages Migration Framework

A Claude Code agent framework that autonomously converts .NET Framework 4.8 Web Forms applications to .NET 10 Razor Pages using Microsoft Clean Architecture. It decomposes requirements, plans the conversion, and executes it screen by screen — with two mandatory human review gates before any code is touched.


What it does

The framework operates in three phases separated by human checkpoints:

Phase 0: Decompose ──► [Human Review] ──► Phase 1: Plan ──► [Human Review] ──► Phase 2: Convert

Phase 0 — Decompose. Claude reads every .aspx, .aspx.cs, and .ascx file and produces:

  • A Requirements.md covering every screen, every field, every validator, and every security rule
  • A security analysis flagging PII fields, CSRF gaps, SQL injection surface, and IDOR risks
  • A code-behind audit mapping every event handler to a business operation with complexity ratings
  • A Clean Architecture layer assignment for every .cs file in the project
  • Auto-detection of which scenario (small or large) fits the application

Phase 1 — Plan. Claude reads Requirements.md and produces:

  • migration-manifest.json — every file classified, layered, and given complexity + story points
  • ConversionPlan.md — per-screen target file paths, PageModel skeletons, field mappings, security remediations, and skill execution order

Phase 2 — Convert. Claude scaffolds the Clean Architecture solution, then converts infrastructure, bootstrap, data, shared controls, pages, cross-cutting concerns, and tests — in dependency order, with build validation between layers.


Clean Architecture scenarios

The framework auto-detects which structure fits your application during Phase 0. You can override the choice before approving requirements.

Scenario 1 — Small App

Use when: ≤ ~20 pages, no external API consumers, single team, simple CRUD.

src/
  {AppName}.Domain/          ← entities, value objects, domain interfaces, specifications
  {AppName}.Infrastructure/  ← EF Core, repositories, identity, external services
  {AppName}.Web/             ← Razor Pages (PageModels inject IRepository<T> directly)
tests/
  {AppName}.Tests/

PageModels call repositories directly from Domain — no MediatR, no Application layer. Keeps the solution simple for apps that don't need the extra abstraction.

Scenario 2 — Large App

Use when: > ~20 pages, external API consumers (mobile / third-party), multiple teams, full CQRS.

src/
  {AppName}.Domain/          ← entities, value objects, domain interfaces, domain events
  {AppName}.Application/     ← MediatR commands/queries, DTOs, FluentValidation, AutoMapper
  {AppName}.Infrastructure/  ← EF Core, repositories, identity, external services
  {AppName}.Api/             ← ASP.NET Core Minimal API, Swagger, API versioning
  {AppName}.Web/             ← Razor Pages consuming Api via typed HttpClient only
tests/
  {AppName}.{Layer}.Tests/   ← one test project per layer (five total)

The Web project never touches the database. All data access goes through the API. The API is independently deployable and versioned.


Prerequisites

Tool Minimum version Install
.NET SDK 10.x winget install Microsoft.DotNet.SDK.10
Node.js 18+ winget install OpenJS.NodeJS.LTS
npm bundled with Node
Claude Code CLI latest npm install -g @anthropic-ai/claude-code

Installation

1. Clone or copy this framework

git clone <repo-url> net-migration-framework
cd net-migration-framework

2. Run the install script

User-level install only (installs MCP servers to your profile, no project changes):

.\install.ps1

Full install into a target project (also deploys all framework files):

.\install.ps1 -ProjectPath "C:\Code\MyLegacyWebFormsApp"

With source control tokens for PR creation:

.\install.ps1 -ProjectPath "C:\Code\MyLegacyApp" -GitHubPat "ghp_xxxx"
# or
.\install.ps1 -ProjectPath "C:\Code\MyLegacyApp" -AzureDevOpsPat "your-pat"

The script:

  • Validates all prerequisites
  • Copies dotnet-mcp, nuget-mcp, and mslearn-mcp to ~/.claude/mcp-servers/ and runs npm install in each
  • Merges MCP server registrations into your user-level ~/.claude/settings.json
  • If -ProjectPath is given: deploys CLAUDE.md, .mcp.json, .claude/settings.json, agents, skills, and docs/ templates into the project
  • Smoke-tests all three MCP servers with node --check

3. (If deploying manually)

If you did not use -ProjectPath, copy these files to your project root:

CLAUDE.md            → {project root}/CLAUDE.md
project-mcp.json     → {project root}/.mcp.json
project-settings.json → {project root}/.claude/settings.json
claude-agents/       → {project root}/.claude/agents/
skills/              → {project root}/.claude/skills/
docs/                → {project root}/docs/

Running the migration

cd C:\Code\MyLegacyWebFormsApp
claude

Then type:

start migration

Claude will run Phase 0 automatically and stop when it's done.

Keyword triggers

Say this What happens
start migration Runs from current position in state
requirements approved Sets gate and begins Phase 1
plan approved Sets gate and begins Phase 2
migration status Prints current state from docs/migration-state.json
reset migration Asks for confirmation, then clears state

Human review gates

Gate 1 — after Phase 0: Review docs/Requirements.md and docs/clean-arch-layer-summary.md. The layer summary shows which scenario was detected and why. If the wrong scenario was chosen, edit docs/migration-state.json and change "scenario": "small" or "scenario": "large" before approving. For Scenario 2, also review docs/api-surface.md which shows the derived API endpoint table.

Gate 2 — after Phase 1: Review docs/ConversionPlan.md, especially the Manual-only entries. Pages flagged Manual-only (VB.NET code-behind, dynamic control generation, deeply nested UpdatePanel) are excluded from automation and listed in the final PR description.


File structure

net-migration-framework/
├── README.md                          ← you are here
├── CLAUDE.md                          ← orchestrator instructions (copy to project root)
├── install.ps1                        ← PowerShell install script
├── project-mcp.json                   ← project-level MCP config (→ .mcp.json)
├── project-settings.json              ← project-level Claude settings
│
├── mcp-servers/
│   ├── dotnet-mcp/index.js            ← dotnet CLI wrapper (build, test, format, ef)
│   ├── nuget-mcp/index.js             ← NuGet API (search, versions, replacements)
│   └── mslearn-mcp/index.js           ← Microsoft Learn documentation search
│
├── claude-agents/
│   ├── project-analyzer.md            ← reads project, writes docs/project-inventory.md
│   ├── requirements-extractor.md      ← Phase 0 loop over all pages
│   ├── conversion-planner-agent.md    ← Phase 1 (audit + plan)
│   ├── file-converter.md              ← converts a single screen
│   ├── build-validator.md             ← runs dotnet build + test, categorises errors
│   └── pr-creator.md                  ← builds and opens PR
│
├── skills/
│   ├── phase0-decompose/
│   │   ├── screen-decomposer/         ← extracts fields, controls, routes from .aspx
│   │   ├── security-analyzer/         ← auth, PII, injection, CSRF per screen
│   │   ├── codebehind-auditor/        ← maps event handlers → business operations
│   │   ├── shared-control-extractor/  ← inventories .ascx controls + dependency order
│   │   ├── clean-arch-mapper/         ← detects scenario, maps every .cs to a layer
│   │   └── requirements-writer/       ← merges all Phase 0 output into Requirements.md
│   ├── phase1-plan/
│   │   ├── net-migration-audit/       ← classifies every file → migration-manifest.json
│   │   └── conversion-planner/        ← produces ConversionPlan.md
│   └── phase2-convert/
│       ├── clean-arch-scaffold/       ← creates the solution structure (Scenario 1 or 2)
│       ├── csproj-migration/          ← .csproj → SDK-style net10.0
│       ├── nuget-upgrade/             ← packages.config → PackageReference
│       ├── webconfig-migration/       ← Web.config → appsettings.json
│       ├── globalasax-to-program/     ← Global.asax → Program.cs
│       ├── ef6-to-efcore/             ← Entity Framework 6 → EF Core 10
│       ├── aspx-to-razor/             ← .aspx + .aspx.cs → .cshtml + PageModel
│       ├── htmlhelper-to-taghelper/   ← @Html.* → Tag Helpers
│       ├── sync-to-async/             ← sync DB calls → async/await + CancellationToken
│       ├── auth-migration/            ← FormsAuthentication → cookie auth / Identity
│       ├── bundling-migration/        ← BundleConfig → LibMan + esbuild
│       └── migration-test-gen/        ← generates xUnit + Moq + FluentAssertions tests
│
└── docs/
    ├── migration-state.json           ← state machine (phase, gates, per-screen status)
    ├── Requirements.md                ← generated by Phase 0
    └── ConversionPlan.md              ← generated by Phase 1

MCP servers

Three Node.js MCP servers extend Claude Code's capabilities:

dotnet-mcp

Wraps the dotnet CLI. Tools: dotnet_build, dotnet_test, dotnet_format, dotnet_ef_migrations_add, dotnet_ef_database_update, dotnet_list_packages, dotnet_version. Used by build-validator and ef6-to-efcore.

nuget-mcp

Queries the NuGet API. Tools: nuget_search, nuget_get_versions, nuget_latest_compatible, nuget_find_replacement. The replacement table includes 20+ known mappings (EntityFramework → EF Core, Unity/Ninject → built-in DI, Web.Optimization → LibMan, etc.). Used by nuget-upgrade.

mslearn-mcp

Queries learn.microsoft.com. Tools: mslearn_search, mslearn_get_article, mslearn_api_lookup, mslearn_migration_guide, mslearn_search_breaking_changes. Hardcoded migration guide URLs for: aspnet-to-aspnetcore, ef6-to-efcore, membership-to-identity, clean-architecture, razor-pages, auth-cookie, tag-helpers, and more. Used by all Phase 2 skills before converting any .NET Framework API.


Phase 2 conversion layer order

Skills run in this order. Each layer is build-validated before the next begins.

Layer Skills Writes to
Scaffold clean-arch-scaffold src/ solution structure
Infrastructure csproj-migration, nuget-upgrade all .csproj files
Bootstrap globalasax-to-program, webconfig-migration Program.cs, appsettings.json
Data ef6-to-efcore Infrastructure/Data/
Shared UI (ascx converter) Web/Pages/Shared/, view components
Page UI aspx-to-razor, htmlhelper-to-taghelper Web/Pages/ (+ Api/Endpoints/ for Scenario 2)
Cross-cutting sync-to-async, auth-migration, bundling-migration across all layers
Tests migration-test-gen tests/

Scenario 2 additions in Page UI layer: for each page, aspx-to-razor also generates the MediatR command/query handler in Application/UseCases/ and the Minimal API endpoint in Api/Endpoints/. The PageModel in Web/Pages/ injects a typed HttpClient wrapper ({Entity}ApiClient) rather than a repository.


Retry and failure handling

  • Each screen gets up to 3 retry attempts if conversion fails or the build breaks
  • After 3 failures, the screen is marked failed in docs/migration-state.json, errors are logged to docs/build-errors.md, and conversion continues with the next screen
  • Screens that cannot be automated (VB.NET code-behind, dynamic control generation, deeply nested UpdatePanel) are flagged Manual-only with the reason. They are excluded from conversion and listed in the PR description

State machine

All progress is tracked in docs/migration-state.json. If Claude Code is interrupted, running start migration resumes from the last completed step.

Key fields:

{
  "phase": 0,
  "phaseStatus": "awaiting-review",
  "scenario": "small",
  "requirementsApproved": false,
  "planApproved": false,
  "lastProcessedPage": "Admin/Users/Edit.aspx",
  "screens": [
    {
      "path": "Admin/Users/Edit.aspx",
      "status": "converted",
      "complexity": "Medium",
      "manualOnly": false,
      "blockedBy": []
    }
  ]
}

Packages used in converted output

All scenarios

  • Ardalis.GuardClauses — guard clauses for domain validation
  • Ardalis.Result — discriminated result type (replaces throwing exceptions for expected failures)
  • Ardalis.Specification — specification pattern for EF Core queries
  • Microsoft.EntityFrameworkCore.SqlServer — EF Core 10 SQL Server provider
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore — ASP.NET Core Identity

Scenario 2 additional packages

  • MediatR — CQRS command/query dispatching
  • FluentValidation — command/query validation
  • AutoMapper — entity → DTO mapping
  • Swashbuckle.AspNetCore — Swagger / OpenAPI
  • Asp.Versioning.Http — API versioning

Test projects

  • xUnit — test framework
  • Moq — mocking
  • FluentAssertions — readable assertions
  • Microsoft.AspNetCore.Mvc.Testing — integration testing with WebApplicationFactory

Limitations

  • VB.NET code-behind is flagged Manual-only. The framework only converts C# Web Forms.
  • Dynamic control generation (controls added in Page_Load at runtime) cannot be fully automated.
  • Third-party Web Forms controls (Telerik, DevExpress, Infragistics) require manual replacement.
  • ASMX web services are not in scope — convert to Minimal API endpoints manually.
  • The framework targets SQL Server via EF Core. Other databases need Infrastructure/DependencyInjection.cs edits after scaffolding.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors