aspnetcore
aspnetcore copied to clipboard
ValidateOnStart doesn't validate Options on startup
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
In Program.cs I have the following section of code:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddOptions<Settings>()
.Bind(builder.Configuration.GetSection("Settings"))
.Validate(_ =>
{
Console.WriteLine("Validating options");
return false;
})
.ValidateOnStart();
However, validation of Settings does not occur until IOptions<Settings> is first injected when the first web request is receivied, or if the launch configuration is set to launch a browser with the swagger page.
Expected Behavior
ValidateOnStart should trigger the .Validate() validation to run on app startup
Steps To Reproduce
- Create a new .NET 8 Web Project using the 'Web API' template
- Edit
Program.csto contain the following code:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddOptions<Settings>()
.Bind(builder.Configuration.GetSection("Settings"))
.Validate(_ =>
{
Console.WriteLine("Validating options");
return false;
})
.ValidateOnStart();
var app = builder.Build();
app.UseHttpsRedirection();
app.Run();
public record Settings
{
public required string TestProperty { get; init; }
}
- Modify
launchSettings.jsonto contain the following (remove launch of swagger on startup from the configuration):
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1232",
"sslPort": 44334
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Exceptions (if any)
No response
.NET Version
8.0.205
Anything else?
.NET SDK:
Version: 8.0.205
Commit: 3e1383b780
Workload version: 8.0.200-manifests.818b3449
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22621
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.205\
.NET workloads installed:
There are no installed workloads to display.
Host:
Version: 8.0.5
Architecture: x64
Commit: 087e15321b
.NET SDKs installed:
6.0.423 [C:\Program Files\dotnet\sdk]
8.0.105 [C:\Program Files\dotnet\sdk]
8.0.205 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
I'm having the same issue myself, @efie45 are you able to solve this by any means?
@bitlab-ruizhi, I left this open in case someone saw it and had suggestions but I believe the issue is that by default, IIS doesn't start up the project until the first request is initiated by design. So your 'validateOnStartup' call does eventually run, but not until a request first comes in. AFAIK there are possibly settings in IIS to 'run' the app on startup which would trigger the validation, but it's not available in IISExpress.
@bitlab-ruizhi @efie45 Catching up on some issue triage here. Can you verify if you are able to repro this in 8.0.400?
Here's the behavior I see for the provided repro:
$ dotnet run
Building...
Validating options
fail: Microsoft.Extensions.Hosting.Internal.Host[11]
Hosting failed to start
Microsoft.Extensions.Options.OptionsValidationException: A validation error has occurred.
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd[TArg](String name, Func`3 createOptions, TArg factoryArgument)
at Microsoft.Extensions.DependencyInjection.OptionsBuilderExtensions.<>c__DisplayClass0_1`1.<ValidateOnStart>b__1()
at Microsoft.Extensions.Options.StartupValidator.Validate()
--- End of stack trace from previous location ---
at Microsoft.Extensions.Options.StartupValidator.Validate()
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
Unhandled exception. Microsoft.Extensions.Options.OptionsValidationException: A validation error has occurred.
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd[TArg](String name, Func`3 createOptions, TArg factoryArgument)
at Microsoft.Extensions.DependencyInjection.OptionsBuilderExtensions.<>c__DisplayClass0_1`1.<ValidateOnStart>b__1()
at Microsoft.Extensions.Options.StartupValidator.Validate()
--- End of stack trace from previous location ---
at Microsoft.Extensions.Options.StartupValidator.Validate()
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at Program.<Main>$(String[] args) in /Users/captainsafia/git/tests/issue-56453/Program.cs:line 17
Went with the exact same project setup as mentioned above. From my testing, the bug only happen when you use Visual Studio Debug mode and start with debugging (F5). In this particular setup, the program will start without any problem when inspected from the output from the project itself, which is {ProjectName} - ASP.NET Core Web Server
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.
See our Issue Management Policies for more information.