Skip to content
This repository was archived by the owner on Aug 24, 2025. It is now read-only.

Commit b485493

Browse files
committed
Enable nullable reference types
1 parent 21efde6 commit b485493

File tree

29 files changed

+293
-254
lines changed

29 files changed

+293
-254
lines changed

Directory.Build.props

Lines changed: 80 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,88 @@
11
<Project>
2-
<PropertyGroup>
3-
<LangVersion>latest</LangVersion>
4-
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
5-
<AnalysisLevel>latest</AnalysisLevel>
6-
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
7-
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
8-
<EnableNETAnalyzers>true</EnableNETAnalyzers>
9-
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
10-
<ImplicitUsings>enable</ImplicitUsings>
11-
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
12-
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
13-
<RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
14-
<!--
2+
<PropertyGroup>
3+
<LangVersion>latest</LangVersion>
4+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
5+
<AnalysisLevel>latest</AnalysisLevel>
6+
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
7+
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
8+
<EnableNETAnalyzers>true</EnableNETAnalyzers>
9+
<Nullable>enable</Nullable>
10+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
11+
<ImplicitUsings>enable</ImplicitUsings>
12+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
13+
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
14+
<RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
15+
<!--
1516
CA2007: Consider calling ConfigureAwait on the awaited task
1617
MA0004: Use Task.ConfigureAwait(false) as the current SynchronizationContext is not needed
1718
CA1056: Change the type of property 'Url' from 'string' to 'System.Uri'
1819
CA1054: Change the type of parameter of the method to allow a Uri to be passed as a 'System.Uri' object
1920
CA1055: Change the return type of method from 'string' to 'System.Uri'
2021
-->
21-
<NoWarn>$(NoWarn);CA2007;CA1056;CA1054;CA1055;MA0004;RCS1090</NoWarn>
22-
<NoError>$(NoError);CA2007;CA1056;CA1054;CA1055;MA0004;RCS1090</NoError>
23-
<Deterministic>true</Deterministic>
24-
<Features>strict</Features>
25-
<ReportAnalyzer>true</ReportAnalyzer>
26-
</PropertyGroup>
27-
<ItemGroup>
28-
<Using Include="System.Globalization"/>
29-
<Using Include="System.Text.Json"/>
30-
<Using Include="System.FormattableString" Static="True"/>
31-
<Using Include="System.Console" Static="True"/>
32-
<Using Include="System.Security.Cryptography"/>
33-
<Using Include="System.Diagnostics.CodeAnalysis"/>
34-
<Using Include="System.Text.Json.Serialization"/>
35-
<Using Include="System.Linq.Expressions"/>
36-
<Using Include="System.Reflection"/>
37-
<Using Include="System.ComponentModel.DataAnnotations"/>
38-
<Using Include="System.Diagnostics"/>
39-
<Using Include="System.ComponentModel.DataAnnotations.Schema"/>
40-
<Using Include="System.Net"/>
41-
<Using Include="System.Net.Http.Headers"/>
42-
<Using Include="System.Net.Http.Json"/>
43-
<Using Include="System.Text.Json"/>
44-
</ItemGroup>
45-
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
46-
<PackageReference Include="Meziantou.Analyzer">
47-
<PrivateAssets>all</PrivateAssets>
48-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
49-
</PackageReference>
50-
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers">
51-
<PrivateAssets>all</PrivateAssets>
52-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
53-
</PackageReference>
54-
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
55-
<PrivateAssets>all</PrivateAssets>
56-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
57-
</PackageReference>
58-
<PackageReference Include="AsyncFixer">
59-
<PrivateAssets>all</PrivateAssets>
60-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
61-
</PackageReference>
62-
<PackageReference Include="Asyncify">
63-
<PrivateAssets>all</PrivateAssets>
64-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
65-
</PackageReference>
66-
<PackageReference Include="SonarAnalyzer.CSharp">
67-
<PrivateAssets>all</PrivateAssets>
68-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
69-
</PackageReference>
70-
<PackageReference Include="SecurityCodeScan.VS2019">
71-
<PrivateAssets>all</PrivateAssets>
72-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
73-
</PackageReference>
74-
<PackageReference Include="Roslynator.Analyzers">
75-
<PrivateAssets>all</PrivateAssets>
76-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
77-
</PackageReference>
78-
<PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers">
79-
<PrivateAssets>all</PrivateAssets>
80-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
81-
</PackageReference>
82-
</ItemGroup>
83-
<ItemGroup>
84-
<AdditionalFiles Include="$(MSBuildThisFileDirectory)BannedSymbols.txt" Link="Properties/BannedSymbols.txt"/>
85-
<Compile Include="$(MSBuildThisFileDirectory)/common/AssemblyInfo.cs" Link="Properties/AssemblyInfo.common.cs"/>
86-
</ItemGroup>
22+
<NoWarn>$(NoWarn);CA2007;CA1056;CA1054;CA1055;MA0004;RCS1090</NoWarn>
23+
<NoError>$(NoError);CA2007;CA1056;CA1054;CA1055;MA0004;RCS1090</NoError>
24+
<Deterministic>true</Deterministic>
25+
<Features>strict</Features>
26+
<ReportAnalyzer>true</ReportAnalyzer>
27+
</PropertyGroup>
28+
<ItemGroup>
29+
<Using Include="System.Globalization"/>
30+
<Using Include="System.Text.Json"/>
31+
<Using Include="System.FormattableString" Static="True"/>
32+
<Using Include="System.Console" Static="True"/>
33+
<Using Include="System.Security.Cryptography"/>
34+
<Using Include="System.Diagnostics.CodeAnalysis"/>
35+
<Using Include="System.Text.Json.Serialization"/>
36+
<Using Include="System.Linq.Expressions"/>
37+
<Using Include="System.Reflection"/>
38+
<Using Include="System.ComponentModel.DataAnnotations"/>
39+
<Using Include="System.Diagnostics"/>
40+
<Using Include="System.ComponentModel.DataAnnotations.Schema"/>
41+
<Using Include="System.Net"/>
42+
<Using Include="System.Net.Http.Headers"/>
43+
<Using Include="System.Net.Http.Json"/>
44+
<Using Include="System.Text.Json"/>
45+
</ItemGroup>
46+
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
47+
<PackageReference Include="Meziantou.Analyzer">
48+
<PrivateAssets>all</PrivateAssets>
49+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
50+
</PackageReference>
51+
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers">
52+
<PrivateAssets>all</PrivateAssets>
53+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
54+
</PackageReference>
55+
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
56+
<PrivateAssets>all</PrivateAssets>
57+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
58+
</PackageReference>
59+
<PackageReference Include="AsyncFixer">
60+
<PrivateAssets>all</PrivateAssets>
61+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
62+
</PackageReference>
63+
<PackageReference Include="Asyncify">
64+
<PrivateAssets>all</PrivateAssets>
65+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
66+
</PackageReference>
67+
<PackageReference Include="SonarAnalyzer.CSharp">
68+
<PrivateAssets>all</PrivateAssets>
69+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
70+
</PackageReference>
71+
<PackageReference Include="SecurityCodeScan.VS2019">
72+
<PrivateAssets>all</PrivateAssets>
73+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
74+
</PackageReference>
75+
<PackageReference Include="Roslynator.Analyzers">
76+
<PrivateAssets>all</PrivateAssets>
77+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
78+
</PackageReference>
79+
<PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers">
80+
<PrivateAssets>all</PrivateAssets>
81+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
82+
</PackageReference>
83+
</ItemGroup>
84+
<ItemGroup>
85+
<AdditionalFiles Include="$(MSBuildThisFileDirectory)BannedSymbols.txt" Link="Properties/BannedSymbols.txt"/>
86+
<Compile Include="$(MSBuildThisFileDirectory)/common/AssemblyInfo.cs" Link="Properties/AssemblyInfo.common.cs"/>
87+
</ItemGroup>
8788
</Project>

src/ASPNETCore2JwtAuthentication.DataLayer/Context/ApplicationDbContext.cs

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ public ApplicationDbContext(DbContextOptions options) : base(options)
99
{
1010
}
1111

12-
public virtual DbSet<User> Users { set; get; }
13-
public virtual DbSet<Role> Roles { set; get; }
14-
public virtual DbSet<UserRole> UserRoles { get; set; }
15-
public virtual DbSet<UserToken> UserTokens { get; set; }
12+
public virtual DbSet<User> Users { set; get; } = default!;
13+
public virtual DbSet<Role> Roles { set; get; } = default!;
14+
public virtual DbSet<UserRole> UserRoles { get; set; } = default!;
15+
public virtual DbSet<UserToken> UserTokens { get; set; } = default!;
1616

1717
protected override void OnModelCreating(ModelBuilder modelBuilder)
1818
{
@@ -26,38 +26,40 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
2626

2727
// Custom application mappings
2828
modelBuilder.Entity<User>(entity =>
29-
{
30-
entity.Property(e => e.Username).HasMaxLength(450).IsRequired();
31-
entity.HasIndex(e => e.Username).IsUnique();
32-
entity.Property(e => e.Password).IsRequired();
33-
entity.Property(e => e.SerialNumber).HasMaxLength(450);
34-
});
29+
{
30+
entity.Property(e => e.Username).HasMaxLength(450).IsRequired();
31+
entity.HasIndex(e => e.Username).IsUnique();
32+
entity.Property(e => e.Password).IsRequired();
33+
entity.Property(e => e.SerialNumber).HasMaxLength(450);
34+
});
3535

3636
modelBuilder.Entity<Role>(entity =>
37-
{
38-
entity.Property(e => e.Name).HasMaxLength(450).IsRequired();
39-
entity.HasIndex(e => e.Name).IsUnique();
40-
});
37+
{
38+
entity.Property(e => e.Name).HasMaxLength(450).IsRequired();
39+
entity.HasIndex(e => e.Name).IsUnique();
40+
});
4141

4242
modelBuilder.Entity<UserRole>(entity =>
43-
{
44-
entity.HasKey(e => new { e.UserId, e.RoleId });
45-
entity.HasIndex(e => e.UserId);
46-
entity.HasIndex(e => e.RoleId);
47-
entity.Property(e => e.UserId);
48-
entity.Property(e => e.RoleId);
49-
entity.HasOne(d => d.Role).WithMany(p => p.UserRoles).HasForeignKey(d => d.RoleId);
50-
entity.HasOne(d => d.User).WithMany(p => p.UserRoles).HasForeignKey(d => d.UserId);
51-
});
43+
{
44+
entity.HasKey(e => new { e.UserId, e.RoleId });
45+
entity.HasIndex(e => e.UserId);
46+
entity.HasIndex(e => e.RoleId);
47+
entity.Property(e => e.UserId);
48+
entity.Property(e => e.RoleId);
49+
entity.HasOne(d => d.Role).WithMany(p => p.UserRoles)
50+
.HasForeignKey(d => d.RoleId);
51+
entity.HasOne(d => d.User).WithMany(p => p.UserRoles)
52+
.HasForeignKey(d => d.UserId);
53+
});
5254

5355
modelBuilder.Entity<UserToken>(entity =>
54-
{
55-
entity.HasOne(ut => ut.User)
56-
.WithMany(u => u.UserTokens)
57-
.HasForeignKey(ut => ut.UserId);
56+
{
57+
entity.HasOne(ut => ut.User)
58+
.WithMany(u => u.UserTokens)
59+
.HasForeignKey(ut => ut.UserId);
5860

59-
entity.Property(ut => ut.RefreshTokenIdHash).HasMaxLength(450).IsRequired();
60-
entity.Property(ut => ut.RefreshTokenIdHashSource).HasMaxLength(450);
61-
});
61+
entity.Property(ut => ut.RefreshTokenIdHash).HasMaxLength(450).IsRequired();
62+
entity.Property(ut => ut.RefreshTokenIdHashSource).HasMaxLength(450);
63+
});
6264
}
6365
}

src/ASPNETCore2JwtAuthentication.DataLayer/Context/ApplicationDbContextFactory.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@ public ApplicationDbContext CreateDbContext(string[] args)
1414
var basePath = Directory.GetCurrentDirectory();
1515
WriteLine($"Using `{basePath}` as the BasePath");
1616
var configuration = new ConfigurationBuilder()
17-
.SetBasePath(basePath)
18-
.AddJsonFile("appsettings.json")
19-
.Build();
17+
.SetBasePath(basePath)
18+
.AddJsonFile("appsettings.json")
19+
.Build();
2020
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
21-
var connectionString = configuration.GetConnectionString("DefaultConnection")
22-
.Replace("|DataDirectory|", Path.Combine(basePath, "wwwroot", "app_data"),
23-
StringComparison.OrdinalIgnoreCase);
21+
var defaultConnection = configuration.GetConnectionString("DefaultConnection");
22+
if (string.IsNullOrWhiteSpace(defaultConnection))
23+
{
24+
throw new InvalidOperationException("defaultConnection is null");
25+
}
26+
27+
var connectionString = defaultConnection.Replace("|DataDirectory|",
28+
Path.Combine(basePath, "wwwroot", "app_data"),
29+
StringComparison.OrdinalIgnoreCase);
2430
builder.UseSqlServer(connectionString);
2531
return new ApplicationDbContext(builder.Options);
2632
}

src/ASPNETCore2JwtAuthentication.DomainClasses/Role.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@ namespace ASPNETCore2JwtAuthentication.DomainClasses;
22

33
public class Role
44
{
5-
public Role()
6-
{
7-
UserRoles = new HashSet<UserRole>();
8-
}
5+
public Role() => UserRoles = new HashSet<UserRole>();
96

107
public int Id { get; set; }
11-
public string Name { get; set; }
8+
public required string Name { get; set; } = default!;
129

1310
public virtual ICollection<UserRole> UserRoles { get; set; }
1411
}

src/ASPNETCore2JwtAuthentication.DomainClasses/User.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ public User()
1010

1111
public int Id { get; set; }
1212

13-
public string Username { get; set; }
13+
public required string Username { get; set; } = default!;
1414

15-
public string Password { get; set; }
15+
public required string Password { get; set; } = default!;
1616

17-
public string DisplayName { get; set; }
17+
public string? DisplayName { get; set; }
1818

1919
public bool IsActive { get; set; }
2020

@@ -25,7 +25,7 @@ public User()
2525
/// or an admin changes his Roles or stat/IsActive,
2626
/// create a new `SerialNumber` GUID and store it in the DB.
2727
/// </summary>
28-
public string SerialNumber { get; set; }
28+
public string? SerialNumber { get; set; }
2929

3030
public virtual ICollection<UserRole> UserRoles { get; set; }
3131

src/ASPNETCore2JwtAuthentication.DomainClasses/UserRole.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ public class UserRole
55
public int UserId { get; set; }
66
public int RoleId { get; set; }
77

8-
public virtual User User { get; set; }
9-
public virtual Role Role { get; set; }
8+
public virtual User User { get; set; } = default!;
9+
public virtual Role Role { get; set; } = default!;
1010
}

src/ASPNETCore2JwtAuthentication.DomainClasses/UserToken.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ public class UserToken
44
{
55
public int Id { get; set; }
66

7-
public string AccessTokenHash { get; set; }
7+
public string? AccessTokenHash { get; set; }
88

99
public DateTimeOffset AccessTokenExpiresDateTime { get; set; }
1010

11-
public string RefreshTokenIdHash { get; set; }
11+
public required string RefreshTokenIdHash { get; set; } = default!;
1212

13-
public string RefreshTokenIdHashSource { get; set; }
13+
public string? RefreshTokenIdHashSource { get; set; }
1414

1515
public DateTimeOffset RefreshTokenExpiresDateTime { get; set; }
1616

1717
public int UserId { get; set; }
18-
public virtual User User { get; set; }
18+
public virtual User User { get; set; } = default!;
1919
}

src/ASPNETCore2JwtAuthentication.IntegrationTests/Base/CustomWebApplicationFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ protected override IHost CreateHost(IHostBuilder builder)
1414
// How to override settings ...
1515
builder.ConfigureHostConfiguration(config =>
1616
{
17-
config.AddInMemoryCollection(new Dictionary<string, string>
17+
config.AddInMemoryCollection(new Dictionary<string, string?>
1818
{
1919
{
2020
"ConnectionStrings:SqlServer:ApplicationDbContextConnection",
@@ -32,7 +32,7 @@ protected override IHost CreateHost(IHostBuilder builder)
3232
return host;
3333
}
3434

35-
protected override IWebHostBuilder CreateWebHostBuilder()
35+
protected override IWebHostBuilder? CreateWebHostBuilder()
3636
{
3737
var builder = base.CreateWebHostBuilder();
3838
builder?.ConfigureLogging(logging =>

0 commit comments

Comments
 (0)