Skip to content

Crash w/ Data Annotations Validation - Regression in RC1 #92276

Closed
@nwoolls

Description

@nwoolls

Description

An application will crash, either on startup or at runtime, with Data Annotations Validation on RC1 if the options class inherits from a Dictionary<T1, T2>.

Reproduction Steps

mkdir spl-dotnet-8-rc1-data-validation-exception
cd spl-dotnet-8-rc1-data-validation-exception
dotnet new mvc
code .

Add the following class:

namespace spl_dotnet_8_rc1_data_validation_exception;

public class SampleOptions : Dictionary<string, string> { }

Add the following to Program.cs:

builder.Services.AddOptions<SampleOptions>("Sample")
    .ValidateDataAnnotations()
    .ValidateOnStart();
dotnet run

Expected behavior

Building...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5056
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /path/to/spl-dotnet-8-rc1-data-validation-exception

Actual behavior

Building...
fail: Microsoft.Extensions.Hosting.Internal.Host[11]
      Hosting failed to start
      System.Reflection.TargetParameterCountException: Parameter count mismatch.
         at System.Reflection.MethodBaseInvoker.ThrowTargetParameterCountException()
         at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
         at Microsoft.Extensions.Options.DataAnnotationValidateOptions`1.TryValidateOptions(Object options, String qualifiedName, List`1 results, List`1& errors, HashSet`1& visited)
         at Microsoft.Extensions.Options.DataAnnotationValidateOptions`1.Validate(String name, TOptions options)
         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()
         at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
Unhandled exception. System.Reflection.TargetParameterCountException: Parameter count mismatch.
   at System.Reflection.MethodBaseInvoker.ThrowTargetParameterCountException()
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.Options.DataAnnotationValidateOptions`1.TryValidateOptions(Object options, String qualifiedName, List`1 results, List`1& errors, HashSet`1& visited)
   at Microsoft.Extensions.Options.DataAnnotationValidateOptions`1.Validate(String name, TOptions options)
   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()
   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 /path/to/spl-dotnet-8-rc1-data-validation-exception/Program.cs:line 33

Regression?

This works fine in the various .NET 8 preview builds, and works fine in .NET 6 and 7. This seems to be a regression in .NET 8 RC1.

Known Workarounds

None - must downgrade to the last .NET 8 preview build.

Configuration

No response

Other information

A global.json makes it clear this is a regression.

Working:

{
  "sdk": {
    "version": "8.0.100-preview.7.23376.3",
//    "rollForward": "latestMajor",
    "allowPrerelease": true
  }
}

Fails:

{
  "sdk": {
    "version": "8.0.100-preview.7.23376.3",
    "rollForward": "latestMajor",
    "allowPrerelease": true
  }
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions