Skip to content

upgrade to dotnet 10 - prompt sample - #101

Open
LBHTKarki wants to merge 2 commits into
masterfrom
feat/upgrade-dotnet-to-10
Open

LBHTKarki wants to merge 2 commits into
masterfrom
feat/upgrade-dotnet-to-10

Conversation

@LBHTKarki

@LBHTKarki LBHTKarki commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

PR summary: .NET 8 → .NET 10

This PR upgrades the contracts-api solution from .NET 8 to .NET 10. Package versions and application behaviour are unchanged except where the .NET 10 SDK otherwise fails restore or build, plus the hosting bootstrap needed to drop obsolete WebHost APIs without rewriting Startup or the Lambda entry point.

Final setup

Target framework, CI, Docker, Lambda packaging

  • ContractsApi and ContractsApi.Tests: net8.0net10.0
  • Dockerfiles: mcr.microsoft.com/dotnet/sdk:8.0sdk:10.0
  • CircleCI docker-dotnet executor: sdk:10.0
  • serverless.yml: runtime: dotnet10; artifact ./bin/release/net10.0/contracts-api.zip
  • build.sh / build.cmd: --framework net10.0 and zip under net10.0

No global.json. The SDK 10 Docker/CI images pin the toolchain.

Restore compatibility

Both projects already use TreatWarningsAsErrors. The .NET 10 SDK audits transitive packages by default; restore then surfaced NU1902/NU1903 on existing transitives (for example Microsoft.Data.SqlClient, Newtonsoft.Json 9.0.1, Npgsql 4.1.3). Those packages were not upgraded. NuGetAuditMode is direct so restore still audits direct references only.

Local / Docker hosting (ASPDEPR008)

WebHost / IWebHost / IWebHostBuilder.Build() are obsolete in ASP.NET Core 10. Program.cs no longer uses WebHost.CreateDefaultBuilder. Local and Docker dotnet ContractsApi.dll use the documented replacement that still supports Startup:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    });

CreateWebHostBuilder was renamed to CreateHostBuilder (IHostBuilder) so WebApplicationFactory<Startup> builds an IHost instead of calling obsolete IWebHostBuilder.Build(). Startup is unchanged. ASPDEPR008 is not in NoWarn (the API project still suppresses XML-doc 1591 only).

WebApplication.CreateBuilder was not used: that model cannot keep UseStartup and would require a Lambda hosting package upgrade.

AWS Lambda (unchanged path)

Lambda does not use Program.Main. The deployed handler is still:

ContractsApi::ContractsApi.LambdaEntryPoint::FunctionHandlerAsync

LambdaEntryPoint still inherits APIGatewayProxyFunction (Amazon.Lambda.AspNetCoreServer 5.1.1) and still calls Init(IWebHostBuilder) with UseStartup<Startup>(). The Lambda library creates its own host and registers the Lambda server instead of Kestrel.

Tests

MockWebApplicationFactory now follows the generic-host path. That exposed two issues the old WebHost path hid; both are fixed in the factory only:

  1. X-Ray. Startup registers X-Ray for all AWS services before the fixture's ConfigureServices runs. Fixture DynamoDB calls happen during host build with no active segment, and appsettings.json sets XRay:UseRuntimeErrors. The factory now sets AWS_XRAY_CONTEXT_MISSING=LOG_ERROR via EnsureEnvVarConfigured.
  2. DI validation. Host.CreateDefaultBuilder enables ValidateOnBuild in Development; WebHost.CreateDefaultBuilder did not. The Hackney.Core.Testing fixtures fail that check (singleton IDynamoDbFixture consuming scoped IDynamoDBContext; ISnsEventVerifier needing unregistered IAmazonSQS). Neither is resolved through this provider. The factory sets ValidateOnBuild = false via UseDefaultServiceProvider. Scope validation stays on.

DynamoDbMockWebApplicationFactory has the same shape but is unused; it was left alone.

Files that differ from master for this upgrade

  • Target framework / SDK images / serverless.yml / build.sh / build.cmd / CircleCI
  • ContractsApi/Program.cs — generic host
  • ContractsApi/ContractsApi.csprojnet10.0, NuGetAuditMode, no ASPDEPR008
  • ContractsApi.Tests/ContractsApi.Tests.csprojnet10.0, NuGetAuditMode, no ASPDEPR008
  • ContractsApi.Tests/MockWebApplicationFactory.cs — X-Ray env var and ValidateOnBuild = false

LambdaEntryPoint.cs, Startup.cs, and all PackageReference versions are unchanged. Amazon.Lambda.Tools remains 4.0.0 in build.sh.

Validation

  • Debug and Release builds succeed on the .NET 10 SDK with no ASPDEPR008.
  • Automated tests: 48 passed, 0 failed, 0 skipped with TZ=UTC, DynamoDB Local on :8000, LocalStack on :4566.
  • Local dotnet run starts Kestrel, serves Swagger UI, and returns the same healthcheck and contracts responses as the pre-hosting-change build.
  • dotnet lambda package --framework net10.0 succeeded.

Known limitations (pre-existing, not fixed)

  • Local GET /api/v1/healthcheck/ping returns 500 (Type Contract does not have the DynamoDBTable attribute applied to it) and /swagger/v1/swagger.json returns 404. Swagger UI and the contracts endpoints respond. Identical before and after this PR.
  • DynamoDbGatewayTests.PatchContractSuccessfullyUpdatesAContract can fail under TZ=Europe/London (DynamoDbDateTimeConverter plus AutoFixture DateTime). It passes under TZ=UTC.

Intentionally not in this PR

  • Vulnerability remediation or a general NuGet upgrade (Microsoft.CodeAnalysis.NetAnalyzers 6.0.0, EF 3.1.3, Swashbuckle, xunit, Hackney.Core.*, AWS SDK, Amazon.Lambda.AspNetCoreServer 5.1.1, and so on).
  • Minimal-hosting rewrite to WebApplication.CreateBuilder / inlining Startup.
  • Pre-existing warnings (NETSDK1206 / Libuv RIDs, Newtonsoft.Json version conflicts).
  • Terraform, database Docker, README, or unrelated documentation.

How to verify

dotnet restore ContractsApi.sln
dotnet build ContractsApi.sln
TZ=UTC dotnet test ContractsApi.sln

Tests need DynamoDB Local (:8000) and LocalStack (:4566), as in docker-compose / CircleCI build-and-test. Deploy packaging uses build.sh / serverless.yml with dotnet10 and net10.0.

@LBHTKarki
LBHTKarki requested a review from a team as a code owner September 18, 2026 14:50
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
D Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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.

1 participant