225 lines
8.2 KiB
C#
225 lines
8.2 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using Microsoft.AspNetCore.Mvc.DataAnnotations;
|
|
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
|
|
using Microsoft.AspNetCore.Mvc.Internal;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
|
using Microsoft.Extensions.Localization;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|
{
|
|
internal class TestModelMetadataProvider : DefaultModelMetadataProvider
|
|
{
|
|
// Creates a provider with all the defaults - includes data annotations
|
|
public static IModelMetadataProvider CreateDefaultProvider(IStringLocalizerFactory stringLocalizerFactory = null)
|
|
{
|
|
var detailsProviders = new IMetadataDetailsProvider[]
|
|
{
|
|
new DefaultBindingMetadataProvider(),
|
|
new DefaultValidationMetadataProvider(),
|
|
new DataAnnotationsMetadataProvider(
|
|
new TestOptionsManager<MvcDataAnnotationsLocalizationOptions>(),
|
|
stringLocalizerFactory),
|
|
new DataMemberRequiredBindingMetadataProvider(),
|
|
};
|
|
|
|
var compositeDetailsProvider = new DefaultCompositeMetadataDetailsProvider(detailsProviders);
|
|
return new DefaultModelMetadataProvider(compositeDetailsProvider, new TestOptionsManager<MvcOptions>());
|
|
}
|
|
|
|
public static IModelMetadataProvider CreateDefaultProvider(IList<IMetadataDetailsProvider> providers)
|
|
{
|
|
var detailsProviders = new List<IMetadataDetailsProvider>()
|
|
{
|
|
new DefaultBindingMetadataProvider(),
|
|
new DefaultValidationMetadataProvider(),
|
|
new DataAnnotationsMetadataProvider(
|
|
new TestOptionsManager<MvcDataAnnotationsLocalizationOptions>(),
|
|
stringLocalizerFactory: null),
|
|
new DataMemberRequiredBindingMetadataProvider(),
|
|
};
|
|
|
|
detailsProviders.AddRange(providers);
|
|
|
|
var compositeDetailsProvider = new DefaultCompositeMetadataDetailsProvider(detailsProviders);
|
|
return new DefaultModelMetadataProvider(compositeDetailsProvider, new TestOptionsManager<MvcOptions>());
|
|
}
|
|
|
|
public static IModelMetadataProvider CreateProvider(IList<IMetadataDetailsProvider> providers)
|
|
{
|
|
var detailsProviders = new List<IMetadataDetailsProvider>();
|
|
if (providers != null)
|
|
{
|
|
detailsProviders.AddRange(providers);
|
|
}
|
|
|
|
var compositeDetailsProvider = new DefaultCompositeMetadataDetailsProvider(detailsProviders);
|
|
return new DefaultModelMetadataProvider(compositeDetailsProvider, new TestOptionsManager<MvcOptions>());
|
|
}
|
|
|
|
private readonly TestModelMetadataDetailsProvider _detailsProvider;
|
|
|
|
public TestModelMetadataProvider()
|
|
: this(new TestModelMetadataDetailsProvider())
|
|
{
|
|
}
|
|
|
|
private TestModelMetadataProvider(TestModelMetadataDetailsProvider detailsProvider)
|
|
: base(
|
|
new DefaultCompositeMetadataDetailsProvider(new IMetadataDetailsProvider[]
|
|
{
|
|
new DefaultBindingMetadataProvider(),
|
|
new DefaultValidationMetadataProvider(),
|
|
new DataAnnotationsMetadataProvider(
|
|
new TestOptionsManager<MvcDataAnnotationsLocalizationOptions>(),
|
|
stringLocalizerFactory: null),
|
|
detailsProvider
|
|
}),
|
|
new TestOptionsManager<MvcOptions>())
|
|
{
|
|
_detailsProvider = detailsProvider;
|
|
}
|
|
|
|
public IMetadataBuilder ForType(Type type)
|
|
{
|
|
var key = ModelMetadataIdentity.ForType(type);
|
|
|
|
var builder = new MetadataBuilder(key);
|
|
_detailsProvider.Builders.Add(builder);
|
|
return builder;
|
|
}
|
|
|
|
public IMetadataBuilder ForType<TModel>()
|
|
{
|
|
return ForType(typeof(TModel));
|
|
}
|
|
|
|
public IMetadataBuilder ForProperty(Type containerType, string propertyName)
|
|
{
|
|
var property = containerType.GetRuntimeProperty(propertyName);
|
|
Assert.NotNull(property);
|
|
|
|
var key = ModelMetadataIdentity.ForProperty(property.PropertyType, propertyName, containerType);
|
|
|
|
var builder = new MetadataBuilder(key);
|
|
_detailsProvider.Builders.Add(builder);
|
|
return builder;
|
|
}
|
|
|
|
public IMetadataBuilder ForProperty<TContainer>(string propertyName)
|
|
{
|
|
return ForProperty(typeof(TContainer), propertyName);
|
|
}
|
|
|
|
private class TestModelMetadataDetailsProvider :
|
|
IBindingMetadataProvider,
|
|
IDisplayMetadataProvider,
|
|
IValidationMetadataProvider
|
|
{
|
|
public List<MetadataBuilder> Builders { get; } = new List<MetadataBuilder>();
|
|
|
|
public void CreateBindingMetadata(BindingMetadataProviderContext context)
|
|
{
|
|
foreach (var builder in Builders)
|
|
{
|
|
builder.Apply(context);
|
|
}
|
|
}
|
|
|
|
public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
|
|
{
|
|
foreach (var builder in Builders)
|
|
{
|
|
builder.Apply(context);
|
|
}
|
|
}
|
|
|
|
public void CreateValidationMetadata(ValidationMetadataProviderContext context)
|
|
{
|
|
foreach (var builder in Builders)
|
|
{
|
|
builder.Apply(context);
|
|
}
|
|
}
|
|
}
|
|
|
|
public interface IMetadataBuilder
|
|
{
|
|
IMetadataBuilder BindingDetails(Action<BindingMetadata> action);
|
|
|
|
IMetadataBuilder DisplayDetails(Action<DisplayMetadata> action);
|
|
|
|
IMetadataBuilder ValidationDetails(Action<ValidationMetadata> action);
|
|
}
|
|
|
|
private class MetadataBuilder : IMetadataBuilder
|
|
{
|
|
private List<Action<BindingMetadata>> _bindingActions = new List<Action<BindingMetadata>>();
|
|
private List<Action<DisplayMetadata>> _displayActions = new List<Action<DisplayMetadata>>();
|
|
private List<Action<ValidationMetadata>> _valiationActions = new List<Action<ValidationMetadata>>();
|
|
|
|
private readonly ModelMetadataIdentity _key;
|
|
|
|
public MetadataBuilder(ModelMetadataIdentity key)
|
|
{
|
|
_key = key;
|
|
}
|
|
|
|
public void Apply(BindingMetadataProviderContext context)
|
|
{
|
|
if (_key.Equals(context.Key))
|
|
{
|
|
foreach (var action in _bindingActions)
|
|
{
|
|
action(context.BindingMetadata);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Apply(DisplayMetadataProviderContext context)
|
|
{
|
|
if (_key.Equals(context.Key))
|
|
{
|
|
foreach (var action in _displayActions)
|
|
{
|
|
action(context.DisplayMetadata);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Apply(ValidationMetadataProviderContext context)
|
|
{
|
|
if (_key.Equals(context.Key))
|
|
{
|
|
foreach (var action in _valiationActions)
|
|
{
|
|
action(context.ValidationMetadata);
|
|
}
|
|
}
|
|
}
|
|
|
|
public IMetadataBuilder BindingDetails(Action<BindingMetadata> action)
|
|
{
|
|
_bindingActions.Add(action);
|
|
return this;
|
|
}
|
|
|
|
public IMetadataBuilder DisplayDetails(Action<DisplayMetadata> action)
|
|
{
|
|
_displayActions.Add(action);
|
|
return this;
|
|
}
|
|
|
|
public IMetadataBuilder ValidationDetails(Action<ValidationMetadata> action)
|
|
{
|
|
_valiationActions.Add(action);
|
|
return this;
|
|
}
|
|
}
|
|
}
|
|
} |