Skip to content

Migrate ASP.NET MVC 5 / .NET 4.5.1 app to ASP.NET Core on .NET 9#22

Open
devin-ai-integration[bot] wants to merge 3 commits into
masterfrom
devin/1780674307-aspnetcore-net9-migration
Open

Migrate ASP.NET MVC 5 / .NET 4.5.1 app to ASP.NET Core on .NET 9#22
devin-ai-integration[bot] wants to merge 3 commits into
masterfrom
devin/1780674307-aspnetcore-net9-migration

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot commented Jun 5, 2026

Summary

Full-framework migration of the SampleMvcWebApp blogging demo from ASP.NET MVC 5 / .NET Framework 4.5.1 to ASP.NET Core on net9.0. All 5 projects are now SDK-style, EF6 is replaced by EF Core 9, and the legacy GenericServices 1.0.9 package is replaced by an in-repo compat library so controllers/views/DTOs keep their original shape.

Why a compat library instead of EfCore.GenericServices

The app is tightly coupled to the old GenericServices surface: EfGenericDto override hooks (SetupSecondaryData/CreateDataFromDto/UpdateDataFromDto), action-parameter service injection, and the ISuccessOrErrors result type used throughout controllers. EfCore.GenericServices exposes a fundamentally different ICrudServices API and cannot reproduce these patterns. Per the task note ("you may need to implement some service methods manually"), a faithful EF Core + AutoMapper reimplementation of the original interfaces was the lowest-risk path. New project: GenericServices/.

Key changes by layer

  • Projects/config: all .csproj → SDK-style net9.0; removed every packages.config, Web.config, App.config, Global.asax, App_Start/, Autofac modules, AssemblyInfo.cs. Added appsettings.json + launchSettings.json.
  • DataLayer (EF Core): SampleWebAppDb : DbContext, IGenericServicesDbContext with constructor DbContextOptions, Fluent API in OnModelCreating (Post→Blog FK, Post↔Tag many-to-many), SaveChanges hook for LastUpdated, and ExtraValidation enforcing Tag.Slug uniqueness (was EF6 ValidateEntity). DataLayerInitialise now uses EnsureCreated() + XML seed.
  • GenericServices compat lib: EfGenericDto<TData,TDto> (+ async), ISuccessOrErrors/<T>, SaveChangesWithChecking (DataAnnotations + IValidatableObject + ExtraValidation), 13 service interfaces/impls projecting via AutoMapper ProjectTo.
  • Web: Program.cs minimal hosting; built-in DI via AddServiceLayer(); DB provider selectable through config (Sqlite default for local dev, SqlServer available). Controllers inherit Core MVC and use [FromServices] for action-parameter service injection; MvcHtmlString→raw string + @Html.Raw.
  • Views: added _ViewImports.cshtml (tag helpers + usings), _Layout uses direct <link>/<script> instead of bundles, removed Views/Web.config, static assets moved to wwwroot/.
  • Tests: converted to net9.0 xUnit on EF Core InMemory; old Autofac/SignalR/System.Web tests (which tested removed infrastructure) replaced with focused data-layer + service-layer CRUD tests. 12 passing.

Verification

  • dotnet build clean across the solution; dotnet test → 12/12 pass.
  • App runs (dotnet run), seeds SQLite, and all pages return 200 (Home, Posts/Tags/Blogs + Async variants, Create/Edit/Details, secondary-data dropdowns populate).

Notes

  • Bootstrap 3 / jQuery 1.10 assets retained to keep the existing Razor markup working (a Bootstrap 5 upgrade would require rewriting all view markup); deferred as out-of-scope.
  • DelegateDecompiler/Mono.Reflection dropped — the compat library computes aggregate fields (e.g. PostsCount) via AutoMapper projection conventions instead.

Link to Devin session: https://app.devin.ai/sessions/97ae13da2ed64c0c821a10a57d4cf380
Requested by: @dillonvargo


Devin Review

Status Commit
⚪ Not started

Run Devin Review

💡 Connect your GitHub account to enable automatic code reviews.

Open in Devin Review (Staging)

…ET 9

- Convert all projects to SDK-style net9.0; remove packages.config/Web.config/App.config
- Replace EF6 with EF Core 9 (DbContext, Fluent API, EnsureCreated + seed)
- Add GenericServices compat library (EF Core + AutoMapper) preserving the
  original EfGenericDto/ISuccessOrErrors service surface
- Replace Global.asax/OWIN/Autofac/SignalR with Program.cs minimal hosting + built-in DI
- Migrate controllers to ASP.NET Core MVC ([FromServices] action injection)
- Migrate Razor views (_ViewImports, tag helpers, direct link/script tags, wwwroot)
- Convert Tests to net9.0 xUnit using EF Core in-memory (12 passing)
- Use SQLite for local dev (SqlServer provider selectable via config)

Co-Authored-By: Dillon Vargo <dillonvargo@gmail.com>
@devin-ai-integration
Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration Bot and others added 2 commits June 5, 2026 16:03
ASP.NET Core's validation visitor invokes all model getters during model
binding. On the posted-back Post DTO the Tags collection is null, so the
TagNames computed getter (Tags.Select(...)) threw ArgumentNullException on
Post Create/Edit. Guard the getter to return empty when Tags is null.

Co-Authored-By: Dillon Vargo <dillonvargo@gmail.com>
Co-Authored-By: Dillon Vargo <dillonvargo@gmail.com>
@devin-ai-integration
Copy link
Copy Markdown
Author

devin-ai-integration Bot commented Jun 5, 2026

Runtime test results — migrated app on .NET 9

Ran the migrated app locally (dotnet run, SQLite seeded on startup) at http://localhost:5000 and exercised the golden-path CRUD flows through the browser UI. All assertions passed. One real bug was found and fixed during testing (now covered by a regression test).

Post Create with secondary data (the previously-broken area) — PASS

The Create form populates the Bloggers dropdown (4) + Tags multiselect (8); submitting creates the post with the correct blogger and tag names.

Post create form
Post created in list

Tag CRUD (create / validate / edit / delete) — PASS

Tags list
Tag created

Post details persisted + regression (Blogs list, PostsAsync) — PASS

Post details
Posts async

Assertions

  • It should perform full Tag CRUD (create, validate, edit, delete) — passed
  • It should create a Post with blogger dropdown + tag multiselect — passed
  • It should show Post details persisted correctly — passed
  • It should edit a Post, preserving blogger + tags — passed
  • It should delete a Post — passed
  • It should render Blogs list + async PostsAsync controller (regression) — passed

Bug found & fixed during testing

Post Create/Edit initially crashed with NullReferenceException: ASP.NET Core's validation visitor invokes the TagNames computed getter on the posted-back DTO where Tags is null. Fixed by null-guarding the getter on all 4 Post DTOs + added a regression test. All 13 xUnit tests pass.

No CI is configured on this repo, so there were no checks to wait on.

Devin session: https://app.devin.ai/sessions/97ae13da2ed64c0c821a10a57d4cf380

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants