| File: ModelBinding\Validation\DefaultUnionValidationStrategy.cs | Web Access |
| Project: Microsoft.AspNetCore.Mvc.Core.csproj (Microsoft.AspNetCore.Mvc.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable enable using System.Runtime.CompilerServices; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation; internal sealed class DefaultUnionValidationStrategy : IValidationStrategy { private readonly IModelMetadataProvider _metadataProvider; public DefaultUnionValidationStrategy(IModelMetadataProvider metadataProvider) { _metadataProvider = metadataProvider; } public IEnumerator<ValidationEntry> GetChildren(ModelMetadata metadata, string key, object model) { var hasValueProperty = false; using var enumerator = DefaultComplexObjectValidationStrategy.Instance.GetChildren(metadata, key, model); while (enumerator.MoveNext()) { var entry = enumerator.Current; if (IsUnionValueProperty(entry.Metadata, model.GetType())) { hasValueProperty = true; } yield return entry; } if (!hasValueProperty) { // IUnion.Value can be implemented explicitly. yield return new ValidationEntry( metadata is DefaultModelMetadata defaultMetadata ? defaultMetadata.CreateUnionValueMetadata() : _metadataProvider.GetMetadataForType(typeof(object)), ModelNames.CreatePropertyModelName(key, nameof(IUnion.Value)), () => ((IUnion)model).Value); } } internal static bool IsUnionValueProperty(ModelMetadata metadata, Type unionType) { if (metadata.MetadataKind != ModelMetadataKind.Property || metadata.PropertyName != nameof(IUnion.Value)) { return false; } var getter = metadata is DefaultModelMetadata propertyMetadata ? propertyMetadata.Details.Key.PropertyInfo?.GetMethod : metadata.ContainerType?.GetProperty(nameof(IUnion.Value))?.GetMethod; var unionGetter = unionType.GetInterfaceMap(typeof(IUnion)).TargetMethods[0]; return getter is not null && (getter.DeclaringType == typeof(IUnion) || getter.GetBaseDefinition() == unionGetter.GetBaseDefinition()); } }