Skip to content

Commit 8ee6af2

Browse files
WIP
1 parent 5290602 commit 8ee6af2

8 files changed

Lines changed: 412 additions & 22 deletions

Directory.Packages.props

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
55
<ToolingPackagesVersion>1.1.1.18932</ToolingPackagesVersion>
6-
<AccessToNugetFeed>false</AccessToNugetFeed>
6+
<AccessToNugetFeed Condition="'$(AccessToNugetFeed)' == ''">false</AccessToNugetFeed>
77
<RestoreSources>
88
https://api.nuget.org/v3/index.json;
99
</RestoreSources>
@@ -19,6 +19,8 @@
1919
<PackageVersion Include="ContentFeedNuget" Version="$(ToolingPackagesVersion)" />
2020
</ItemGroup>
2121
<ItemGroup>
22+
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="10.0.6" />
23+
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.4.0" />
2224
<PackageVersion Include="AspNet.Security.OAuth.GitHub" Version="10.0.0" />
2325
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.5.0" />
2426
<PackageVersion Include="Azure.Identity" Version="1.21.0" />
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
using EssentialCSharp.Web.Areas.Identity.Data;
2+
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
23
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
34
using Microsoft.EntityFrameworkCore;
45

56
namespace EssentialCSharp.Web.Data;
67

7-
public class EssentialCSharpWebContext(DbContextOptions options) : IdentityDbContext<EssentialCSharpWebUser>(options)
8+
public class EssentialCSharpWebContext(DbContextOptions<EssentialCSharpWebContext> options)
9+
: IdentityDbContext<EssentialCSharpWebUser>(options), IDataProtectionKeyContext
810
{
11+
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } = null!;
12+
913
protected override void OnModelCreating(ModelBuilder builder)
1014
{
1115
base.OnModelCreating(builder);
12-
// Customize the ASP.NET Identity model and override the defaults if needed.
13-
// For example, you can rename the ASP.NET Identity table names and more.
14-
// Add your customizations after calling base.OnModelCreating(builder);
1516
}
1617
}

EssentialCSharp.Web/DatabaseMigrationService.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33

44
namespace EssentialCSharp.Web;
55

6-
public class DatabaseMigrationService(IServiceScopeFactory services) : BackgroundService
6+
/// <summary>
7+
/// Runs EF Core migrations synchronously in <see cref="StartAsync"/> so the schema
8+
/// is fully applied before the HTTP server begins accepting traffic. This prevents
9+
/// race conditions where a request touches the DataProtectionKeys (or Identity) tables
10+
/// before the migration that creates them has run.
11+
/// </summary>
12+
public class DatabaseMigrationService(IServiceScopeFactory services) : IHostedService
713
{
8-
public IServiceScopeFactory Services { get; } = services;
9-
10-
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
14+
public async Task StartAsync(CancellationToken cancellationToken)
1115
{
12-
using IServiceScope scope = Services.CreateScope();
16+
using IServiceScope scope = services.CreateScope();
1317
EssentialCSharpWebContext context = scope.ServiceProvider.GetRequiredService<EssentialCSharpWebContext>();
14-
await context.Database.MigrateAsync(stoppingToken);
18+
await context.Database.MigrateAsync(cancellationToken);
1519
}
20+
21+
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
1622
}

EssentialCSharp.Web/EssentialCSharp.Web.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
<ItemGroup>
3131
<PackageReference Include="AspNet.Security.OAuth.GitHub" />
32+
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" />
3233
<PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" />
3334
<PackageReference Include="EssentialCSharp.Shared.Models" />
3435
<PackageReference Include="HtmlAgilityPack" />
@@ -38,6 +39,7 @@
3839
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" />
3940
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
4041
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
42+
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" />
4143
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" />
4244
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
4345
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">

EssentialCSharp.Web/Migrations/20260417060024_AddDataProtectionKeys.Designer.cs

Lines changed: 311 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)