Improving logging - model binding
Related to issue #6498: When enabling "Trace" logging for MVC loggers, I should be buried in log messages
This commit is contained in:
parent
f9b246e7ab
commit
c922b0b90d
|
|
@ -1,6 +1,8 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -29,5 +31,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
/// Gets the <see cref="IModelMetadataProvider"/>.
|
||||
/// </summary>
|
||||
public abstract IModelMetadataProvider MetadataProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IServiceProvider"/>.
|
||||
/// </summary>
|
||||
public virtual IServiceProvider Services { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
|||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
|
|
@ -236,10 +237,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAddSingleton<ParameterBinder>(s =>
|
||||
{
|
||||
var options = s.GetRequiredService<IOptions<MvcOptions>>().Value;
|
||||
var loggerFactory = s.GetRequiredService<ILoggerFactory>();
|
||||
var metadataProvider = s.GetRequiredService<IModelMetadataProvider>();
|
||||
var modelBinderFactory = s.GetRequiredService<IModelBinderFactory>();
|
||||
var modelValidatorProvider = new CompositeModelValidatorProvider(options.ModelValidatorProviders);
|
||||
return new ParameterBinder(metadataProvider, modelBinderFactory, modelValidatorProvider);
|
||||
return new ParameterBinder(metadataProvider, modelBinderFactory, modelValidatorProvider, loggerFactory);
|
||||
});
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ using System.Security.Claims;
|
|||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ActionConstraints;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
|
|
@ -98,7 +100,30 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
|
||||
private static readonly Action<ILogger, MethodInfo, string, string, Exception> _inferredParameterSource;
|
||||
private static readonly Action<ILogger, MethodInfo, Exception> _unableToInferParameterSources;
|
||||
|
||||
private static readonly Action<ILogger, IModelBinderProvider[], Exception> _registeredModelBinderProviders;
|
||||
private static readonly Action<ILogger, string, Type, string, Type, Exception> _foundNoValueForPropertyInRequest;
|
||||
private static readonly Action<ILogger, string, string, Type, Exception> _foundNoValueInRequest;
|
||||
private static readonly Action<ILogger, string, Type, Exception> _noPublicSettableProperties;
|
||||
private static readonly Action<ILogger, Type, Exception> _cannotBindToComplexType;
|
||||
private static readonly Action<ILogger, string, Type, Exception> _cannotBindToFilesCollectionDueToUnsupportedContentType;
|
||||
private static readonly Action<ILogger, Type, Exception> _cannotCreateHeaderModelBinder;
|
||||
private static readonly Action<ILogger, Exception> _noFilesFoundInRequest;
|
||||
private static readonly Action<ILogger, string, string, Exception> _noNonIndexBasedFormatFoundForCollection;
|
||||
private static readonly Action<ILogger, string, string, string, string, string, string, Exception> _attemptingToBindCollectionUsingIndices;
|
||||
private static readonly Action<ILogger, string, string, string, string, string, string, Exception> _attemptingToBindCollectionOfKeyValuePair;
|
||||
private static readonly Action<ILogger, string, string, string, Exception> _noKeyValueFormatForDictionaryModelBinder;
|
||||
private static readonly Action<ILogger, Type, string, Type, string, Exception> _attemptingToBindPropertyModel;
|
||||
private static readonly Action<ILogger, Type, string, Type, Exception> _doneAttemptingToBindPropertyModel;
|
||||
private static readonly Action<ILogger, Type, string, Exception> _attemptingToBindModel;
|
||||
private static readonly Action<ILogger, Type, string, Exception> _doneAttemptingToBindModel;
|
||||
private static readonly Action<ILogger, string, Type, Exception> _attemptingToBindParameter;
|
||||
private static readonly Action<ILogger, string, Type, Exception> _doneAttemptingToBindParameter;
|
||||
private static readonly Action<ILogger, Type, string, Type, Exception> _attemptingToBindProperty;
|
||||
private static readonly Action<ILogger, Type, string, Type, Exception> _doneAttemptingToBindProperty;
|
||||
private static readonly Action<ILogger, Type, string, Type, Exception> _attemptingToValidateProperty;
|
||||
private static readonly Action<ILogger, Type, string, Type, Exception> _doneAttemptingToValidateProperty;
|
||||
private static readonly Action<ILogger, string, Type, Exception> _attemptingToValidateParameter;
|
||||
private static readonly Action<ILogger, string, Type, Exception> _doneAttemptingToValidateParameter;
|
||||
private static readonly Action<ILogger, string, Exception> _unsupportedFormatFilterContentType;
|
||||
private static readonly Action<ILogger, string, MediaTypeCollection, Exception> _actionDoesNotSupportFormatFilterContentType;
|
||||
private static readonly Action<ILogger, string, Exception> _cannotApplyFormatFilterContentType;
|
||||
|
|
@ -417,35 +442,161 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
11,
|
||||
"List of registered output formatters, in the following order: {OutputFormatters}");
|
||||
|
||||
_ifMatchPreconditionFailed = LoggerMessage.Define<EntityTagHeaderValue>(
|
||||
LogLevel.Debug,
|
||||
12,
|
||||
"Current request's If-Match header check failed as the file's current etag '{CurrentETag}' does not match with any of the supplied etags.");
|
||||
|
||||
_ifUnmodifiedSincePreconditionFailed = LoggerMessage.Define<DateTimeOffset?, DateTimeOffset?>(
|
||||
LogLevel.Debug,
|
||||
13,
|
||||
"Current request's If-Unmodified-Since header check failed as the file was modified (at '{lastModified}') after the If-Unmodified-Since date '{IfUnmodifiedSinceDate}'.");
|
||||
|
||||
_ifRangeLastModifiedPreconditionFailed = LoggerMessage.Define<DateTimeOffset?, DateTimeOffset?>(
|
||||
LogLevel.Debug,
|
||||
14,
|
||||
"Could not serve range as the file was modified (at {LastModified}) after the if-Range's last modified date '{IfRangeLastModified}'.");
|
||||
|
||||
_ifRangeETagPreconditionFailed = LoggerMessage.Define<EntityTagHeaderValue, EntityTagHeaderValue>(
|
||||
LogLevel.Debug,
|
||||
15,
|
||||
"Could not serve range as the file's current etag '{CurrentETag}' does not match the If-Range etag '{IfRangeETag}'.");
|
||||
|
||||
_notEnabledForRangeProcessing = LoggerMessage.Define(
|
||||
LogLevel.Debug,
|
||||
16,
|
||||
$"The file result has not been enabled for processing range requests. To enable it, set the property '{nameof(FileResult.EnableRangeProcessing)}' on the result to 'true'.");
|
||||
|
||||
_writingRangeToBody = LoggerMessage.Define(
|
||||
LogLevel.Debug,
|
||||
17,
|
||||
"Writing the requested range of bytes to the body...");
|
||||
|
||||
_registeredModelBinderProviders = LoggerMessage.Define<IModelBinderProvider[]>(
|
||||
LogLevel.Debug,
|
||||
12,
|
||||
"Registered model binder providers, in the following order: {ModelBinderProviders}");
|
||||
|
||||
_attemptingToBindPropertyModel = LoggerMessage.Define<Type, string, Type, string>(
|
||||
LogLevel.Debug,
|
||||
13,
|
||||
"Attempting to bind property '{PropertyContainerType}.{PropertyName}' of type '{ModelType}' using the name '{ModelName}' in request data ...");
|
||||
|
||||
_doneAttemptingToBindPropertyModel = LoggerMessage.Define<Type, string, Type>(
|
||||
LogLevel.Debug,
|
||||
14,
|
||||
"Done attempting to bind property '{PropertyContainerType}.{PropertyName}' of type '{ModelType}'.");
|
||||
|
||||
_foundNoValueForPropertyInRequest = LoggerMessage.Define<string, Type, string, Type>(
|
||||
LogLevel.Debug,
|
||||
15,
|
||||
"Could not find a value in the request with name '{ModelName}' for binding property '{PropertyContainerType}.{ModelFieldName}' of type '{ModelType}'.");
|
||||
|
||||
_foundNoValueInRequest = LoggerMessage.Define<string, string, Type>(
|
||||
LogLevel.Debug,
|
||||
16,
|
||||
"Could not find a value in the request with name '{ModelName}' for binding parameter '{ModelFieldName}' of type '{ModelType}'.");
|
||||
|
||||
_noPublicSettableProperties = LoggerMessage.Define<string, Type>(
|
||||
LogLevel.Debug,
|
||||
17,
|
||||
"Could not bind to model with name '{ModelName}' and type '{ModelType}' as the type has no public settable properties.");
|
||||
|
||||
_cannotBindToComplexType = LoggerMessage.Define<Type>(
|
||||
LogLevel.Debug,
|
||||
18,
|
||||
"Could not bind to model of type '{ModelType}' as there were no values in the request for any of the properties.");
|
||||
|
||||
_cannotBindToFilesCollectionDueToUnsupportedContentType = LoggerMessage.Define<string, Type>(
|
||||
LogLevel.Debug,
|
||||
19,
|
||||
"Could not bind to model with name '{ModelName}' and type '{ModelType}' as the request did not have a content type of either 'application/x-www-form-urlencoded' or 'multipart/form-data'.");
|
||||
|
||||
_cannotCreateHeaderModelBinder = LoggerMessage.Define<Type>(
|
||||
LogLevel.Debug,
|
||||
20,
|
||||
"Could not create a binder for type '{ModelType}' as this binder only supports 'System.String' type or a collection of 'System.String'.");
|
||||
|
||||
_noFilesFoundInRequest = LoggerMessage.Define(
|
||||
LogLevel.Debug,
|
||||
21,
|
||||
"No files found in the request to bind the model to.");
|
||||
|
||||
_attemptingToBindParameter = LoggerMessage.Define<string, Type>(
|
||||
LogLevel.Debug,
|
||||
22,
|
||||
"Attempting to bind parameter '{ParameterName}' of type '{ModelType}' ...");
|
||||
|
||||
_doneAttemptingToBindParameter = LoggerMessage.Define<string, Type>(
|
||||
LogLevel.Debug,
|
||||
23,
|
||||
"Done attempting to bind parameter '{ParameterName}' of type '{ModelType}'.");
|
||||
|
||||
_attemptingToBindModel = LoggerMessage.Define<Type, string>(
|
||||
LogLevel.Debug,
|
||||
24,
|
||||
"Attempting to bind model of type '{ModelType}' using the name '{ModelName}' in request data ...");
|
||||
|
||||
_doneAttemptingToBindModel = LoggerMessage.Define<Type, string>(
|
||||
LogLevel.Debug,
|
||||
25,
|
||||
"Done attempting to bind model of type '{ModelType}' using the name '{ModelName}'.");
|
||||
|
||||
_attemptingToValidateParameter = LoggerMessage.Define<string, Type>(
|
||||
LogLevel.Debug,
|
||||
26,
|
||||
"Attempting to validate the bound parameter '{ParameterName}' of type '{ModelType}' ...");
|
||||
|
||||
_doneAttemptingToValidateParameter = LoggerMessage.Define<string, Type>(
|
||||
LogLevel.Debug,
|
||||
27,
|
||||
"Done attempting to validate the bound parameter '{ParameterName}' of type '{ModelType}'.");
|
||||
|
||||
_noNonIndexBasedFormatFoundForCollection = LoggerMessage.Define<string, string>(
|
||||
LogLevel.Debug,
|
||||
28,
|
||||
"Could not bind to collection using a format like {ModelName}=value1&{ModelName}=value2");
|
||||
|
||||
_attemptingToBindCollectionUsingIndices = LoggerMessage.Define<string, string, string, string, string, string>(
|
||||
LogLevel.Debug,
|
||||
29,
|
||||
"Attempting to bind model using indices. Example formats include: " +
|
||||
"[0]=value1&[1]=value2, " +
|
||||
"{ModelName}[0]=value1&{ModelName}[1]=value2, " +
|
||||
"{ModelName}.index=zero&{ModelName}.index=one&{ModelName}[zero]=value1&{ModelName}[one]=value2");
|
||||
|
||||
_attemptingToBindCollectionOfKeyValuePair = LoggerMessage.Define<string, string, string, string, string, string>(
|
||||
LogLevel.Debug,
|
||||
30,
|
||||
"Attempting to bind collection of KeyValuePair. Example formats include: " +
|
||||
"[0].Key=key1&[0].Value=value1&[1].Key=key2&[1].Value=value2, " +
|
||||
"{ModelName}[0].Key=key1&{ModelName}[0].Value=value1&{ModelName}[1].Key=key2&{ModelName}[1].Value=value2, " +
|
||||
"{ModelName}[key1]=value1&{ModelName}[key2]=value2");
|
||||
|
||||
_noKeyValueFormatForDictionaryModelBinder = LoggerMessage.Define<string, string, string>(
|
||||
LogLevel.Debug,
|
||||
33,
|
||||
"Attempting to bind model with name '{ModelName}' using the format {ModelName}[key1]=value1&{ModelName}[key2]=value2");
|
||||
|
||||
_ifMatchPreconditionFailed = LoggerMessage.Define<EntityTagHeaderValue>(
|
||||
LogLevel.Debug,
|
||||
34,
|
||||
"Current request's If-Match header check failed as the file's current etag '{CurrentETag}' does not match with any of the supplied etags.");
|
||||
|
||||
_ifUnmodifiedSincePreconditionFailed = LoggerMessage.Define<DateTimeOffset?, DateTimeOffset?>(
|
||||
LogLevel.Debug,
|
||||
35,
|
||||
"Current request's If-Unmodified-Since header check failed as the file was modified (at '{lastModified}') after the If-Unmodified-Since date '{IfUnmodifiedSinceDate}'.");
|
||||
|
||||
_ifRangeLastModifiedPreconditionFailed = LoggerMessage.Define<DateTimeOffset?, DateTimeOffset?>(
|
||||
LogLevel.Debug,
|
||||
36,
|
||||
"Could not serve range as the file was modified (at {LastModified}) after the if-Range's last modified date '{IfRangeLastModified}'.");
|
||||
|
||||
_ifRangeETagPreconditionFailed = LoggerMessage.Define<EntityTagHeaderValue, EntityTagHeaderValue>(
|
||||
LogLevel.Debug,
|
||||
37,
|
||||
"Could not serve range as the file's current etag '{CurrentETag}' does not match the If-Range etag '{IfRangeETag}'.");
|
||||
|
||||
_notEnabledForRangeProcessing = LoggerMessage.Define(
|
||||
LogLevel.Debug,
|
||||
38,
|
||||
$"The file result has not been enabled for processing range requests. To enable it, set the property '{nameof(FileResult.EnableRangeProcessing)}' on the result to 'true'.");
|
||||
|
||||
_attemptingToBindProperty = LoggerMessage.Define<Type, string, Type>(
|
||||
LogLevel.Debug,
|
||||
39,
|
||||
"Attempting to bind property '{PropertyContainerType}.{PropertyName}' of type '{ModelType}' ...");
|
||||
|
||||
_doneAttemptingToBindProperty = LoggerMessage.Define<Type, string, Type>(
|
||||
LogLevel.Debug,
|
||||
40,
|
||||
"Done attempting to bind property '{PropertyContainerType}.{PropertyName}' of type '{ModelType}'.");
|
||||
|
||||
_attemptingToValidateProperty = LoggerMessage.Define<Type, string, Type>(
|
||||
LogLevel.Debug,
|
||||
41,
|
||||
"Attempting to validate the bound property '{PropertyContainerType}.{PropertyName}' of type '{ModelType}' ...");
|
||||
|
||||
_doneAttemptingToValidateProperty = LoggerMessage.Define<Type, string, Type>(
|
||||
LogLevel.Debug,
|
||||
42,
|
||||
"Done attempting to validate the bound property '{PropertyContainerType}.{PropertyName}' of type '{ModelType}'.");
|
||||
}
|
||||
|
||||
public static void RegisteredOutputFormatters(this ILogger logger, IEnumerable<IOutputFormatter> outputFormatters)
|
||||
|
|
@ -967,6 +1118,200 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
_ifRangeETagPreconditionFailed(logger, currentETag, ifRangeTag, null);
|
||||
}
|
||||
|
||||
public static void RegisteredModelBinderProviders(this ILogger logger, IModelBinderProvider[] providers)
|
||||
{
|
||||
_registeredModelBinderProviders(logger, providers, null);
|
||||
}
|
||||
|
||||
public static void FoundNoValueInRequest(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (!logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var modelMetadata = bindingContext.ModelMetadata;
|
||||
var isProperty = modelMetadata.ContainerType != null;
|
||||
|
||||
if (isProperty)
|
||||
{
|
||||
_foundNoValueForPropertyInRequest(
|
||||
logger,
|
||||
bindingContext.ModelName,
|
||||
modelMetadata.ContainerType,
|
||||
modelMetadata.PropertyName,
|
||||
bindingContext.ModelType,
|
||||
null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_foundNoValueInRequest(
|
||||
logger,
|
||||
bindingContext.ModelName,
|
||||
modelMetadata.PropertyName,
|
||||
bindingContext.ModelType,
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void NoPublicSettableProperties(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
_noPublicSettableProperties(logger, bindingContext.ModelName, bindingContext.ModelType, null);
|
||||
}
|
||||
|
||||
public static void CannotBindToComplexType(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
_cannotBindToComplexType(logger, bindingContext.ModelType, null);
|
||||
}
|
||||
|
||||
public static void CannotBindToFilesCollectionDueToUnsupportedContentType(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
_cannotBindToFilesCollectionDueToUnsupportedContentType(logger, bindingContext.ModelName, bindingContext.ModelType, null);
|
||||
}
|
||||
|
||||
public static void CannotCreateHeaderModelBinder(this ILogger logger, Type modelType)
|
||||
{
|
||||
_cannotCreateHeaderModelBinder(logger, modelType, null);
|
||||
}
|
||||
|
||||
public static void NoFilesFoundInRequest(this ILogger logger)
|
||||
{
|
||||
_noFilesFoundInRequest(logger, null);
|
||||
}
|
||||
|
||||
public static void AttemptingToBindModel(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (!logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var modelMetadata = bindingContext.ModelMetadata;
|
||||
var isProperty = modelMetadata.ContainerType != null;
|
||||
|
||||
if (isProperty)
|
||||
{
|
||||
_attemptingToBindPropertyModel(
|
||||
logger,
|
||||
modelMetadata.ContainerType,
|
||||
modelMetadata.PropertyName,
|
||||
modelMetadata.ModelType,
|
||||
bindingContext.ModelName,
|
||||
null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_attemptingToBindModel(logger, bindingContext.ModelType, bindingContext.ModelName, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoneAttemptingToBindModel(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
var modelMetadata = bindingContext.ModelMetadata;
|
||||
var isProperty = modelMetadata.ContainerType != null;
|
||||
|
||||
if (isProperty)
|
||||
{
|
||||
_doneAttemptingToBindPropertyModel(
|
||||
logger,
|
||||
modelMetadata.ContainerType,
|
||||
modelMetadata.PropertyName,
|
||||
modelMetadata.ModelType,
|
||||
null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_doneAttemptingToBindModel(logger, bindingContext.ModelType, bindingContext.ModelName, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AttemptingToBindParameterOrProperty(this ILogger logger, ParameterDescriptor parameter, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (parameter is ControllerBoundPropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
_attemptingToBindProperty(logger, propertyDescriptor.PropertyInfo.DeclaringType, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_attemptingToBindParameter(logger, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoneAttemptingToBindParameterOrProperty(this ILogger logger, ParameterDescriptor parameter, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (parameter is ControllerBoundPropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
_doneAttemptingToBindProperty(logger, propertyDescriptor.PropertyInfo.DeclaringType, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_doneAttemptingToBindParameter(logger, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AttemptingToValidateParameterOrProperty(this ILogger logger, ParameterDescriptor parameter, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (parameter is ControllerBoundPropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
_attemptingToValidateProperty(logger, propertyDescriptor.PropertyInfo.DeclaringType, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_attemptingToValidateParameter(logger, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoneAttemptingToValidateParameterOrProperty(this ILogger logger, ParameterDescriptor parameter, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (parameter is ControllerBoundPropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
_doneAttemptingToValidateProperty(logger, propertyDescriptor.PropertyInfo.DeclaringType, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_doneAttemptingToValidateParameter(logger, parameter.Name, bindingContext.ModelType, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void NoNonIndexBasedFormatFoundForCollection(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
var modelName = bindingContext.ModelName;
|
||||
_noNonIndexBasedFormatFoundForCollection(logger, modelName, modelName, null);
|
||||
}
|
||||
|
||||
public static void AttemptingToBindCollectionUsingIndices(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
if (!logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var modelName = bindingContext.ModelName;
|
||||
|
||||
var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(bindingContext.ModelType, typeof(IEnumerable<>));
|
||||
if (enumerableType != null)
|
||||
{
|
||||
var elementType = enumerableType.GenericTypeArguments[0];
|
||||
if (elementType.IsGenericType && elementType.GetGenericTypeDefinition().GetTypeInfo() == typeof(KeyValuePair<,>).GetTypeInfo())
|
||||
{
|
||||
_attemptingToBindCollectionOfKeyValuePair(logger, modelName, modelName, modelName, modelName, modelName, modelName, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_attemptingToBindCollectionUsingIndices(logger, modelName, modelName, modelName, modelName, modelName, modelName, null);
|
||||
}
|
||||
|
||||
public static void NoKeyValueFormatForDictionaryModelBinder(this ILogger logger, ModelBindingContext bindingContext)
|
||||
{
|
||||
_noKeyValueFormatForDictionaryModelBinder(
|
||||
logger,
|
||||
bindingContext.ModelName,
|
||||
bindingContext.ModelName,
|
||||
bindingContext.ModelName,
|
||||
null);
|
||||
}
|
||||
|
||||
private static void LogFilterExecutionPlan(
|
||||
ILogger logger,
|
||||
string filterType,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||
|
|
@ -23,8 +24,9 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
private readonly IHttpRequestStreamReaderFactory _readerFactory;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
|
||||
// Used in tests
|
||||
public MvcCoreMvcOptionsSetup(IHttpRequestStreamReaderFactory readerFactory)
|
||||
: this(readerFactory, loggerFactory: null)
|
||||
: this(readerFactory, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ Microsoft.AspNetCore.Mvc.RouteAttribute</Description>
|
|||
<PackageReference Include="Microsoft.AspNetCore.ResponseCaching.Abstractions" Version="$(MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="$(MicrosoftAspNetCoreRoutingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.ClosedGenericMatcher.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsClosedGenericMatcherSourcesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="$(MicrosoftExtensionsFileProvidersAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.HashCodeCombiner.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -14,14 +16,30 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
/// <typeparam name="TElement">Type of elements in the array.</typeparam>
|
||||
public class ArrayModelBinder<TElement> : CollectionModelBinder<TElement>
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Creates a new <see cref="ArrayModelBinder{TElement}"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="elementBinder">
|
||||
/// The <see cref="IModelBinder"/> for binding <typeparamref name="TElement"/>.
|
||||
/// </param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public ArrayModelBinder(IModelBinder elementBinder)
|
||||
: this(elementBinder, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ArrayModelBinder{TElement}"/>.
|
||||
/// </summary>
|
||||
/// <param name="elementBinder">
|
||||
/// The <see cref="IModelBinder"/> for binding <typeparamref name="TElement"/>.
|
||||
/// </param>
|
||||
public ArrayModelBinder(IModelBinder elementBinder)
|
||||
: base(elementBinder)
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public ArrayModelBinder(IModelBinder elementBinder, ILoggerFactory loggerFactory)
|
||||
: base(elementBinder, loggerFactory)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -24,7 +26,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var elementBinder = context.CreateBinder(context.Metadata.ElementMetadata);
|
||||
|
||||
var binderType = typeof(ArrayModelBinder<>).MakeGenericType(elementType);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, elementBinder);
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, elementBinder, loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger?.AttemptingToBindModel(bindingContext);
|
||||
|
||||
// Special logic for body, treat the model name as string.Empty for the top level
|
||||
// object, but allow an override via BinderModelName. The purpose of this is to try
|
||||
// and be similar to the behavior for POCOs bound via traditional model binding.
|
||||
|
|
@ -147,6 +149,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var message = Resources.FormatUnsupportedContentType(httpContext.Request.ContentType);
|
||||
var exception = new UnsupportedContentTypeException(message);
|
||||
bindingContext.ModelState.AddModelError(modelBindingKey, exception, bindingContext.ModelMetadata);
|
||||
_logger?.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +160,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
if (result.HasError)
|
||||
{
|
||||
// Formatter encountered an error. Do not use the model it returned.
|
||||
_logger?.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +187,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
bindingContext.ModelState.AddModelError(modelBindingKey, exception, bindingContext.ModelMetadata);
|
||||
}
|
||||
|
||||
_logger?.DoneAttemptingToBindModel(bindingContext);
|
||||
}
|
||||
|
||||
private bool ShouldHandleException(IInputFormatter formatter)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -11,6 +14,34 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
/// </summary>
|
||||
public class ByteArrayModelBinder : IModelBinder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="ByteArrayModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public ByteArrayModelBinder()
|
||||
: this(NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ByteArrayModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public ByteArrayModelBinder(ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_logger = loggerFactory.CreateLogger<ByteArrayModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task BindModelAsync(ModelBindingContext bindingContext)
|
||||
{
|
||||
|
|
@ -19,10 +50,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
// Check for missing data case 1: There was no <input ... /> element containing this data.
|
||||
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
||||
if (valueProviderResult == ValueProviderResult.None)
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var value = valueProviderResult.FirstValue;
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +76,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
var model = Convert.FromBase64String(value);
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
|
@ -47,8 +83,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.ModelName,
|
||||
exception,
|
||||
bindingContext.ModelMetadata);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -20,7 +22,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
if (context.Metadata.ModelType == typeof(byte[]))
|
||||
{
|
||||
return new ByteArrayModelBinder();
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return new ByteArrayModelBinder(loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -23,18 +25,38 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
private Func<object> _modelCreator;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Creates a new <see cref="CollectionModelBinder{TElement}"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="elementBinder">The <see cref="IModelBinder"/> for binding elements.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public CollectionModelBinder(IModelBinder elementBinder)
|
||||
: this(elementBinder, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CollectionModelBinder{TElement}"/>.
|
||||
/// </summary>
|
||||
/// <param name="elementBinder">The <see cref="IModelBinder"/> for binding elements.</param>
|
||||
public CollectionModelBinder(IModelBinder elementBinder)
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public CollectionModelBinder(IModelBinder elementBinder, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (elementBinder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(elementBinder));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
ElementBinder = elementBinder;
|
||||
Logger = loggerFactory.CreateLogger(GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -42,6 +64,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
/// </summary>
|
||||
protected IModelBinder ElementBinder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> used for logging in this binder.
|
||||
/// </summary>
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual async Task BindModelAsync(ModelBindingContext bindingContext)
|
||||
{
|
||||
|
|
@ -50,9 +77,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
Logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
var model = bindingContext.Model;
|
||||
if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
|
||||
{
|
||||
Logger.FoundNoValueInRequest(bindingContext);
|
||||
|
||||
// If we failed to find data for a top-level model, then generate a
|
||||
// default 'empty' model (or use existing Model) and return it.
|
||||
if (bindingContext.IsTopLevelObject)
|
||||
|
|
@ -65,6 +96,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
}
|
||||
|
||||
Logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
CollectionResult result;
|
||||
if (valueProviderResult == ValueProviderResult.None)
|
||||
{
|
||||
Logger.NoNonIndexBasedFormatFoundForCollection(bindingContext);
|
||||
result = await BindComplexCollection(bindingContext);
|
||||
}
|
||||
else
|
||||
|
|
@ -110,6 +143,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
}
|
||||
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
Logger.DoneAttemptingToBindModel(bindingContext);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -207,6 +241,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Used when the ValueProvider contains the collection to be bound as multiple elements, e.g. foo[0], foo[1].
|
||||
private Task<CollectionResult> BindComplexCollection(ModelBindingContext bindingContext)
|
||||
{
|
||||
Logger.AttemptingToBindCollectionUsingIndices(bindingContext);
|
||||
|
||||
var indexPropertyName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, "index");
|
||||
var valueProviderResultIndex = bindingContext.ValueProvider.GetValue(indexPropertyName);
|
||||
var indexNames = GetIndexNamesFromValueProviderResult(valueProviderResultIndex);
|
||||
|
|
@ -273,7 +309,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
// If we're working with a fixed set of indexes then this is the format like:
|
||||
//
|
||||
// ?parameter.index=zero,one,two¶meter[zero]=0&¶meter[one]=1¶meter[two]=2...
|
||||
// ?parameter.index=zero¶meter.index=one¶meter.index=two¶meter[zero]=0¶meter[one]=1¶meter[two]=2...
|
||||
//
|
||||
// We need to provide this data to the validation system so it can 'replay' the keys.
|
||||
// But we can't just set ValidationState here, because it needs the 'real' model.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -29,6 +31,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
return null;
|
||||
}
|
||||
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
|
||||
// If the model type is ICollection<> then we can call its Add method, so we can always support it.
|
||||
var collectionType = ClosedGenericMatcher.ExtractGenericInterface(modelType, typeof(ICollection<>));
|
||||
if (collectionType != null)
|
||||
|
|
@ -37,7 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var elementBinder = context.CreateBinder(context.MetadataProvider.GetMetadataForType(elementType));
|
||||
|
||||
var binderType = typeof(CollectionModelBinder<>).MakeGenericType(collectionType.GenericTypeArguments);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, elementBinder);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, elementBinder, loggerFactory);
|
||||
}
|
||||
|
||||
// If the model type is IEnumerable<> then we need to know if we can assign a List<> to it, since
|
||||
|
|
@ -53,7 +57,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var elementBinder = context.CreateBinder(context.MetadataProvider.GetMetadataForType(elementType));
|
||||
|
||||
var binderType = typeof(CollectionModelBinder<>).MakeGenericType(enumerableType.GenericTypeArguments);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, elementBinder);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, elementBinder, loggerFactory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ using System.Linq.Expressions;
|
|||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Core;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -16,22 +19,47 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public class ComplexTypeModelBinder : IModelBinder
|
||||
{
|
||||
private readonly IDictionary<ModelMetadata, IModelBinder> _propertyBinders;
|
||||
private readonly ILogger _logger;
|
||||
private Func<object> _modelCreator;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Creates a new <see cref="ComplexTypeModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="propertyBinders">
|
||||
/// The <see cref="IDictionary{TKey, TValue}"/> of binders to use for binding properties.
|
||||
/// </param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public ComplexTypeModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders)
|
||||
: this(propertyBinders, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ComplexTypeModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="propertyBinders">
|
||||
/// The <see cref="IDictionary{TKey, TValue}"/> of binders to use for binding properties.
|
||||
/// </param>
|
||||
public ComplexTypeModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders)
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public ComplexTypeModelBinder(
|
||||
IDictionary<ModelMetadata, IModelBinder> propertyBinders,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (propertyBinders == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propertyBinders));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_propertyBinders = propertyBinders;
|
||||
_logger = loggerFactory.CreateLogger<ComplexTypeModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -42,6 +70,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
if (!CanCreateModel(bindingContext))
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
|
|
@ -106,6 +136,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
}
|
||||
|
||||
bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -199,6 +230,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// level object. So we return false.
|
||||
if (bindingContext.ModelMetadata.Properties.Count == 0)
|
||||
{
|
||||
_logger.NoPublicSettableProperties(bindingContext);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -272,6 +304,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
return true;
|
||||
}
|
||||
|
||||
_logger.CannotBindToComplexType(bindingContext);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +341,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates suitable <see cref="object"/> for given <paramref name="bindingContext"/>.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -28,7 +30,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
propertyBinders.Add(property, context.CreateBinder(property));
|
||||
}
|
||||
|
||||
return new ComplexTypeModelBinder(propertyBinders);
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return new ComplexTypeModelBinder(propertyBinders, loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -15,10 +18,35 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public class DecimalModelBinder : IModelBinder
|
||||
{
|
||||
private readonly NumberStyles _supportedStyles;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="DecimalModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="supportedStyles">The <see cref="NumberStyles"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public DecimalModelBinder(NumberStyles supportedStyles)
|
||||
: this(supportedStyles, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="DecimalModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="supportedStyles">The <see cref="NumberStyles"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public DecimalModelBinder(NumberStyles supportedStyles, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_supportedStyles = supportedStyles;
|
||||
_logger = loggerFactory.CreateLogger<DecimalModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -29,11 +57,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
var modelName = bindingContext.ModelName;
|
||||
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
|
||||
if (valueProviderResult == ValueProviderResult.None)
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
|
||||
// no entry
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -72,13 +105,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelName,
|
||||
metadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(
|
||||
valueProviderResult.ToString()));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
|
|
@ -94,8 +124,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelState.TryAddModelError(modelName, exception, metadata);
|
||||
|
||||
// Conversion failed.
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -21,13 +23,28 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
private readonly IModelBinder _valueBinder;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Creates a new <see cref="DictionaryModelBinder{TKey, TValue}"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="keyBinder">The <see cref="IModelBinder"/> for <typeparamref name="TKey"/>.</param>
|
||||
/// <param name="valueBinder">The <see cref="IModelBinder"/> for <typeparamref name="TValue"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public DictionaryModelBinder(IModelBinder keyBinder, IModelBinder valueBinder)
|
||||
: this(keyBinder, valueBinder, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="DictionaryModelBinder{TKey, TValue}"/>.
|
||||
/// </summary>
|
||||
/// <param name="keyBinder">The <see cref="IModelBinder"/> for <typeparamref name="TKey"/>.</param>
|
||||
/// <param name="valueBinder">The <see cref="IModelBinder"/> for <typeparamref name="TValue"/>.</param>
|
||||
public DictionaryModelBinder(IModelBinder keyBinder, IModelBinder valueBinder)
|
||||
: base(new KeyValuePairModelBinder<TKey, TValue>(keyBinder, valueBinder))
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public DictionaryModelBinder(IModelBinder keyBinder, IModelBinder valueBinder, ILoggerFactory loggerFactory)
|
||||
: base(new KeyValuePairModelBinder<TKey, TValue>(keyBinder, valueBinder, loggerFactory), loggerFactory)
|
||||
{
|
||||
if (valueBinder == null)
|
||||
{
|
||||
|
|
@ -62,6 +79,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
return;
|
||||
}
|
||||
|
||||
Logger.NoKeyValueFormatForDictionaryModelBinder(bindingContext);
|
||||
|
||||
var enumerableValueProvider = bindingContext.ValueProvider as IEnumerableValueProvider;
|
||||
if (enumerableValueProvider == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -31,7 +33,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var valueBinder = context.CreateBinder(context.MetadataProvider.GetMetadataForType(valueType));
|
||||
|
||||
var binderType = typeof(DictionaryModelBinder<,>).MakeGenericType(dictionaryType.GenericTypeArguments);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, keyBinder, valueBinder);
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, keyBinder, valueBinder, loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -15,10 +18,35 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public class DoubleModelBinder : IModelBinder
|
||||
{
|
||||
private readonly NumberStyles _supportedStyles;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="DoubleModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="supportedStyles">The <see cref="NumberStyles"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public DoubleModelBinder(NumberStyles supportedStyles)
|
||||
: this(supportedStyles, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="DoubleModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="supportedStyles">The <see cref="NumberStyles"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public DoubleModelBinder(NumberStyles supportedStyles, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_supportedStyles = supportedStyles;
|
||||
_logger = loggerFactory.CreateLogger<DoubleModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -29,11 +57,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
var modelName = bindingContext.ModelName;
|
||||
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
|
||||
if (valueProviderResult == ValueProviderResult.None)
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
|
||||
// no entry
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -72,13 +105,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelName,
|
||||
metadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(
|
||||
valueProviderResult.ToString()));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
|
|
@ -94,8 +124,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelState.TryAddModelError(modelName, exception, metadata);
|
||||
|
||||
// Conversion failed.
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -13,15 +14,31 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
private readonly bool _suppressBindingUndefinedValueToEnumType;
|
||||
|
||||
public EnumTypeModelBinder(bool supressBindingUndefinedValueToEnumType, Type modelType)
|
||||
: base(modelType)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="EnumTypeModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="suppressBindingUndefinedValueToEnumType">
|
||||
/// Flag to determine if binding to undefined should be suppressed or not.
|
||||
/// </param>
|
||||
/// <param name="modelType">The mdoel type.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>,</param>
|
||||
public EnumTypeModelBinder(
|
||||
bool suppressBindingUndefinedValueToEnumType,
|
||||
Type modelType,
|
||||
ILoggerFactory loggerFactory)
|
||||
: base(modelType, loggerFactory)
|
||||
{
|
||||
if (modelType == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelType));
|
||||
}
|
||||
|
||||
_suppressBindingUndefinedValueToEnumType = supressBindingUndefinedValueToEnumType;
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_suppressBindingUndefinedValueToEnumType = suppressBindingUndefinedValueToEnumType;
|
||||
}
|
||||
|
||||
protected override void CheckModel(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -12,6 +14,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
private readonly MvcOptions _options;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="EnumTypeModelBinderProvider"/>.
|
||||
/// </summary>
|
||||
/// <param name="options">The <see cref="MvcOptions"/>.</param>
|
||||
public EnumTypeModelBinderProvider(MvcOptions options)
|
||||
{
|
||||
_options = options;
|
||||
|
|
@ -27,9 +33,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
if (context.Metadata.IsEnum)
|
||||
{
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return new EnumTypeModelBinder(
|
||||
_options.SuppressBindingUndefinedValueToEnumType,
|
||||
context.Metadata.UnderlyingOrModelType);
|
||||
context.Metadata.UnderlyingOrModelType,
|
||||
loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -15,10 +18,35 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public class FloatModelBinder : IModelBinder
|
||||
{
|
||||
private readonly NumberStyles _supportedStyles;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="FloatModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="supportedStyles">The <see cref="NumberStyles"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public FloatModelBinder(NumberStyles supportedStyles)
|
||||
: this(supportedStyles, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="FloatModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="supportedStyles">The <see cref="NumberStyles"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public FloatModelBinder(NumberStyles supportedStyles, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_supportedStyles = supportedStyles;
|
||||
_logger = loggerFactory.CreateLogger<FloatModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -29,11 +57,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
var modelName = bindingContext.ModelName;
|
||||
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
|
||||
if (valueProviderResult == ValueProviderResult.None)
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
|
||||
// no entry
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -72,13 +105,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelName,
|
||||
metadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor(
|
||||
valueProviderResult.ToString()));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
|
|
@ -94,8 +124,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelState.TryAddModelError(modelName, exception, metadata);
|
||||
|
||||
// Conversion failed.
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -25,19 +27,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
}
|
||||
|
||||
var modelType = context.Metadata.UnderlyingOrModelType;
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
if (modelType == typeof(decimal))
|
||||
{
|
||||
return new DecimalModelBinder(SupportedStyles);
|
||||
return new DecimalModelBinder(SupportedStyles, loggerFactory);
|
||||
}
|
||||
|
||||
if (modelType == typeof(double))
|
||||
{
|
||||
return new DoubleModelBinder(SupportedStyles);
|
||||
return new DoubleModelBinder(SupportedStyles, loggerFactory);
|
||||
}
|
||||
|
||||
if (modelType == typeof(float))
|
||||
{
|
||||
return new FloatModelBinder(SupportedStyles);
|
||||
return new FloatModelBinder(SupportedStyles, loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -16,6 +19,34 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
/// </summary>
|
||||
public class FormCollectionModelBinder : IModelBinder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="FormCollectionModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public FormCollectionModelBinder()
|
||||
: this(NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="FormCollectionModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public FormCollectionModelBinder(ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_logger = loggerFactory.CreateLogger<FormCollectionModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task BindModelAsync(ModelBindingContext bindingContext)
|
||||
{
|
||||
|
|
@ -24,6 +55,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
object model;
|
||||
var request = bindingContext.HttpContext.Request;
|
||||
if (request.HasFormContentType)
|
||||
|
|
@ -33,10 +66,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
}
|
||||
else
|
||||
{
|
||||
_logger.CannotBindToFilesCollectionDueToUnsupportedContentType(bindingContext);
|
||||
model = new EmptyFormCollection();
|
||||
}
|
||||
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
}
|
||||
|
||||
private class EmptyFormCollection : IFormCollection
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ using System;
|
|||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Core;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -34,7 +36,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
if (modelType == typeof(IFormCollection))
|
||||
{
|
||||
return new FormCollectionModelBinder();
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return new FormCollectionModelBinder(loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@ using System.Diagnostics;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -18,6 +21,34 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
/// </summary>
|
||||
public class FormFileModelBinder : IModelBinder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="FormFileModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public FormFileModelBinder()
|
||||
: this(NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="FormFileModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public FormFileModelBinder(ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_logger = loggerFactory.CreateLogger<FormFileModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task BindModelAsync(ModelBindingContext bindingContext)
|
||||
{
|
||||
|
|
@ -26,6 +57,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
var createFileCollection = bindingContext.ModelType == typeof(IFormFileCollection);
|
||||
if (!createFileCollection && !ModelBindingHelper.CanGetCompatibleCollection<IFormFile>(bindingContext))
|
||||
{
|
||||
|
|
@ -58,6 +91,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
if (postedFiles.Count == 0)
|
||||
{
|
||||
// Silently fail if the named file does not exist in the request.
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +103,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Silently fail if no files match. Will bind to an empty collection (treat empty as a success
|
||||
// case and not reach here) if binding to a top-level object.
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -103,6 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
attemptedValue: null);
|
||||
|
||||
bindingContext.Result = ModelBindingResult.Success(value);
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
}
|
||||
|
||||
private async Task GetFormFilesAsync(
|
||||
|
|
@ -128,6 +164,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
postedFiles.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (postedFiles.Count == 0)
|
||||
{
|
||||
_logger.NoFilesFoundInRequest();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.CannotBindToFilesCollectionDueToUnsupportedContentType(bindingContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -27,7 +29,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
modelType == typeof(IFormFileCollection) ||
|
||||
typeof(IEnumerable<IFormFile>).IsAssignableFrom(modelType))
|
||||
{
|
||||
return new FormFileModelBinder();
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return new FormFileModelBinder(loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -14,6 +17,34 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
/// </summary>
|
||||
public class HeaderModelBinder : IModelBinder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="HeaderModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public HeaderModelBinder()
|
||||
: this(NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="HeaderModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public HeaderModelBinder(ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_logger = loggerFactory.CreateLogger<HeaderModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task BindModelAsync(ModelBindingContext bindingContext)
|
||||
{
|
||||
|
|
@ -27,6 +58,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Property name can be null if the model metadata represents a type (rather than a property or parameter).
|
||||
var headerName = bindingContext.FieldName;
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
if (!request.Headers.ContainsKey(headerName))
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
}
|
||||
|
||||
object model;
|
||||
if (bindingContext.ModelType == typeof(string))
|
||||
{
|
||||
|
|
@ -62,6 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
}
|
||||
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -21,12 +24,19 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
if (context.BindingInfo.BindingSource != null &&
|
||||
context.BindingInfo.BindingSource.CanAcceptDataFrom(BindingSource.Header))
|
||||
{
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
var logger = loggerFactory.CreateLogger<HeaderModelBinderProvider>();
|
||||
|
||||
// We only support strings and collections of strings. Some cases can fail
|
||||
// at runtime due to collections we can't modify.
|
||||
if (context.Metadata.ModelType == typeof(string) ||
|
||||
context.Metadata.ElementType == typeof(string))
|
||||
{
|
||||
return new HeaderModelBinder();
|
||||
return new HeaderModelBinder(loggerFactory);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.CannotCreateHeaderModelBinder(context.Metadata.ModelType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -17,13 +20,29 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
private readonly IModelBinder _keyBinder;
|
||||
private readonly IModelBinder _valueBinder;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Creates a new <see cref="KeyValuePair{TKey, TValue}"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="keyBinder">The <see cref="IModelBinder"/> for <typeparamref name="TKey"/>.</param>
|
||||
/// <param name="valueBinder">The <see cref="IModelBinder"/> for <typeparamref name="TValue"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public KeyValuePairModelBinder(IModelBinder keyBinder, IModelBinder valueBinder)
|
||||
: this(keyBinder, valueBinder, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="KeyValuePair{TKey, TValue}"/>.
|
||||
/// </summary>
|
||||
/// <param name="keyBinder">The <see cref="IModelBinder"/> for <typeparamref name="TKey"/>.</param>
|
||||
/// <param name="valueBinder">The <see cref="IModelBinder"/> for <typeparamref name="TValue"/>.</param>
|
||||
public KeyValuePairModelBinder(IModelBinder keyBinder, IModelBinder valueBinder)
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public KeyValuePairModelBinder(IModelBinder keyBinder, IModelBinder valueBinder, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (keyBinder == null)
|
||||
{
|
||||
|
|
@ -35,8 +54,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(valueBinder));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_keyBinder = keyBinder;
|
||||
_valueBinder = valueBinder;
|
||||
_logger = loggerFactory.CreateLogger<KeyValuePairModelBinder<TKey, TValue>>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -47,6 +72,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
throw new ArgumentNullException(nameof(bindingContext));
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
var keyModelName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, "Key");
|
||||
var keyResult = await TryBindStrongModel<TKey>(bindingContext, _keyBinder, "Key", keyModelName);
|
||||
|
||||
|
|
@ -60,6 +87,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
ModelBindingHelper.CastOrDefault<TValue>(valueResult.Model));
|
||||
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -68,6 +96,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.ModelState.TryAddModelError(
|
||||
keyModelName,
|
||||
bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingKeyOrValueAccessor());
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.ModelState.TryAddModelError(
|
||||
valueModelName,
|
||||
bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingKeyOrValueAccessor());
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +116,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var model = new KeyValuePair<TKey, TValue>();
|
||||
bindingContext.Result = ModelBindingResult.Success(model);
|
||||
}
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
}
|
||||
|
||||
internal async Task<ModelBindingResult> TryBindStrongModel<TModel>(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -21,7 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
}
|
||||
|
||||
var modelTypeInfo = context.Metadata.ModelType.GetTypeInfo();
|
||||
if (modelTypeInfo.IsGenericType &&
|
||||
if (modelTypeInfo.IsGenericType &&
|
||||
modelTypeInfo.GetGenericTypeDefinition().GetTypeInfo() == typeof(KeyValuePair<,>).GetTypeInfo())
|
||||
{
|
||||
var typeArguments = modelTypeInfo.GenericTypeArguments;
|
||||
|
|
@ -33,7 +35,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var valueBinder = context.CreateBinder(valueMetadata);
|
||||
|
||||
var binderType = typeof(KeyValuePairModelBinder<,>).MakeGenericType(typeArguments);
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, keyBinder, valueBinder);
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, keyBinder, valueBinder, loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using System;
|
|||
using System.ComponentModel;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -14,15 +17,40 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public class SimpleTypeModelBinder : IModelBinder
|
||||
{
|
||||
private readonly TypeConverter _typeConverter;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="SimpleTypeModelBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="type">The type to create binder for.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public SimpleTypeModelBinder(Type type)
|
||||
: this(type, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SimpleTypeModelBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to create binder for.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public SimpleTypeModelBinder(Type type, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_typeConverter = TypeDescriptor.GetConverter(type);
|
||||
_logger = loggerFactory.CreateLogger<SimpleTypeModelBinder>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -36,10 +64,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
||||
if (valueProviderResult == ValueProviderResult.None)
|
||||
{
|
||||
_logger.FoundNoValueInRequest(bindingContext);
|
||||
|
||||
// no entry
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
_logger.AttemptingToBindModel(bindingContext);
|
||||
|
||||
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
|
||||
|
||||
try
|
||||
|
|
@ -74,6 +107,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
CheckModel(bindingContext, valueProviderResult, model);
|
||||
|
||||
_logger.DoneAttemptingToBindModel(bindingContext);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (Exception exception)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -20,7 +22,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
if (!context.Metadata.IsComplexType)
|
||||
{
|
||||
return new SimpleTypeModelBinder(context.Metadata.ModelType);
|
||||
var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
|
||||
return new SimpleTypeModelBinder(context.Metadata.ModelType, loggerFactory);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ using System.Runtime.CompilerServices;
|
|||
using Microsoft.AspNetCore.Mvc.Core;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||
|
|
@ -22,20 +25,42 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
{
|
||||
private readonly IModelMetadataProvider _metadataProvider;
|
||||
private readonly IModelBinderProvider[] _providers;
|
||||
|
||||
private readonly ConcurrentDictionary<Key, IModelBinder> _cache;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="IServiceProvider"/>.</para>
|
||||
/// <para>Creates a new <see cref="ModelBinderFactory"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="metadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
|
||||
/// <param name="options">The <see cref="IOptions{TOptions}"/> for <see cref="MvcOptions"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(IServiceProvider) + ".")]
|
||||
public ModelBinderFactory(IModelMetadataProvider metadataProvider, IOptions<MvcOptions> options)
|
||||
: this(metadataProvider, options, GetDefaultServices())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ModelBinderFactory"/>.
|
||||
/// </summary>
|
||||
/// <param name="metadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
|
||||
/// <param name="options">The <see cref="IOptions{TOptions}"/> for <see cref="MvcOptions"/>.</param>
|
||||
public ModelBinderFactory(IModelMetadataProvider metadataProvider, IOptions<MvcOptions> options)
|
||||
/// <param name="serviceProvider">The <see cref="IServiceProvider"/>.</param>
|
||||
public ModelBinderFactory(
|
||||
IModelMetadataProvider metadataProvider,
|
||||
IOptions<MvcOptions> options,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
_metadataProvider = metadataProvider;
|
||||
_providers = options.Value.ModelBinderProviders.ToArray();
|
||||
|
||||
_serviceProvider = serviceProvider;
|
||||
_cache = new ConcurrentDictionary<Key, IModelBinder>();
|
||||
|
||||
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
||||
var logger = loggerFactory.CreateLogger<ModelBinderFactory>();
|
||||
logger.RegisteredModelBinderProviders(_providers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -195,6 +220,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return _cache.TryGetValue(new Key(metadata, cacheToken), out binder);
|
||||
}
|
||||
|
||||
private static IServiceProvider GetDefaultServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
private class DefaultModelBinderProviderContext : ModelBinderProviderContext
|
||||
{
|
||||
private readonly ModelBinderFactory _factory;
|
||||
|
|
@ -245,6 +277,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
|
||||
public Dictionary<Key, IModelBinder> Visited { get; }
|
||||
|
||||
public override IServiceProvider Services => _factory._serviceProvider;
|
||||
|
||||
public override IModelBinder CreateBinder(ModelMetadata metadata)
|
||||
{
|
||||
if (metadata == null)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||
{
|
||||
|
|
@ -20,17 +22,47 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
private readonly IModelValidatorProvider _validatorProvider;
|
||||
private readonly ValidatorCache _validatorCache;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="ILoggerFactory"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="ParameterBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="modelMetadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
|
||||
/// <param name="modelBinderFactory">The <see cref="IModelBinderFactory"/>.</param>
|
||||
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that also takes an " + nameof(ILoggerFactory) + ".")]
|
||||
public ParameterBinder(
|
||||
IModelMetadataProvider modelMetadataProvider,
|
||||
IModelBinderFactory modelBinderFactory,
|
||||
IModelValidatorProvider validatorProvider)
|
||||
: this(
|
||||
modelMetadataProvider,
|
||||
modelBinderFactory,
|
||||
validatorProvider,
|
||||
validatorForBackCompatOnly: null,
|
||||
loggerFactory: NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ParameterBinder"/>.
|
||||
/// </summary>
|
||||
/// <param name="modelMetadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
|
||||
/// <param name="modelBinderFactory">The <see cref="IModelBinderFactory"/>.</param>
|
||||
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public ParameterBinder(
|
||||
IModelMetadataProvider modelMetadataProvider,
|
||||
IModelBinderFactory modelBinderFactory,
|
||||
IModelValidatorProvider validatorProvider)
|
||||
: this(modelMetadataProvider, modelBinderFactory, validatorProvider, null)
|
||||
IModelValidatorProvider validatorProvider,
|
||||
ILoggerFactory loggerFactory)
|
||||
: this(
|
||||
modelMetadataProvider,
|
||||
modelBinderFactory,
|
||||
validatorProvider,
|
||||
validatorForBackCompatOnly: null,
|
||||
loggerFactory: loggerFactory)
|
||||
{
|
||||
if (validatorProvider == null)
|
||||
{
|
||||
|
|
@ -39,17 +71,27 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ParameterBinder"/>.
|
||||
/// <para>This constructor is obsolete and will be removed in a future version. The recommended alternative
|
||||
/// is the overload that also takes an <see cref="IModelValidatorProvider"/> and <see cref="ILoggerFactory"/>
|
||||
/// instead of an <see cref="IObjectModelValidator"/>.</para>
|
||||
/// <para>Initializes a new instance of <see cref="ParameterBinder"/>.</para>
|
||||
/// </summary>
|
||||
/// <param name="modelMetadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
|
||||
/// <param name="modelBinderFactory">The <see cref="IModelBinderFactory"/>.</param>
|
||||
/// <param name="validator">The <see cref="IObjectModelValidator"/>.</param>
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative is the overload that takes a " + nameof(IModelValidatorProvider) + " instead of a " + nameof(IObjectModelValidator) + ".")]
|
||||
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended alternative"
|
||||
+ " is the overload that takes an " + nameof(IModelValidatorProvider) + " and " + nameof(ILoggerFactory)
|
||||
+ " instead of an " + nameof(IObjectModelValidator) + ".")]
|
||||
public ParameterBinder(
|
||||
IModelMetadataProvider modelMetadataProvider,
|
||||
IModelBinderFactory modelBinderFactory,
|
||||
IObjectModelValidator validator)
|
||||
: this(modelMetadataProvider, modelBinderFactory, null, validator)
|
||||
: this(
|
||||
modelMetadataProvider,
|
||||
modelBinderFactory,
|
||||
validatorProvider: null,
|
||||
validatorForBackCompatOnly: validator,
|
||||
loggerFactory: NullLoggerFactory.Instance)
|
||||
{
|
||||
// Note: When this obsolete constructor overload is removed, also remember
|
||||
// to remove the validatorForBackCompatOnly field.
|
||||
|
|
@ -64,7 +106,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
IModelMetadataProvider modelMetadataProvider,
|
||||
IModelBinderFactory modelBinderFactory,
|
||||
IModelValidatorProvider validatorProvider,
|
||||
IObjectModelValidator validatorForBackCompatOnly)
|
||||
IObjectModelValidator validatorForBackCompatOnly,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (modelMetadataProvider == null)
|
||||
{
|
||||
|
|
@ -76,13 +119,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
throw new ArgumentNullException(nameof(modelBinderFactory));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_modelMetadataProvider = modelMetadataProvider;
|
||||
_modelBinderFactory = modelBinderFactory;
|
||||
_validatorProvider = validatorProvider;
|
||||
_validatorForBackCompatOnly = validatorForBackCompatOnly;
|
||||
_validatorCache = new ValidatorCache();
|
||||
Logger = loggerFactory.CreateLogger(GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> used for logging in this binder.
|
||||
/// </summary>
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes and binds a model specified by <paramref name="parameter"/>.
|
||||
/// </summary>
|
||||
|
|
@ -200,6 +254,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
parameter.Name);
|
||||
modelBindingContext.Model = value;
|
||||
|
||||
Logger.AttemptingToBindParameterOrProperty(parameter, modelBindingContext);
|
||||
|
||||
var parameterModelName = parameter.BindingInfo?.BinderModelName ?? metadata.BinderModelName;
|
||||
if (parameterModelName != null)
|
||||
{
|
||||
|
|
@ -219,6 +275,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
|
||||
await modelBinder.BindModelAsync(modelBindingContext);
|
||||
|
||||
Logger.DoneAttemptingToBindParameterOrProperty(parameter, modelBindingContext);
|
||||
|
||||
var modelBindingResult = modelBindingContext.Result;
|
||||
|
||||
if (_validatorForBackCompatOnly != null)
|
||||
|
|
@ -237,11 +295,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger.AttemptingToValidateParameterOrProperty(parameter, modelBindingContext);
|
||||
|
||||
EnforceBindRequiredAndValidate(
|
||||
actionContext,
|
||||
metadata,
|
||||
modelBindingContext,
|
||||
modelBindingResult);
|
||||
|
||||
Logger.DoneAttemptingToValidateParameterOrProperty(parameter, modelBindingContext);
|
||||
}
|
||||
|
||||
return modelBindingResult;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
|||
using Microsoft.AspNetCore.Mvc.TestCommon;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
|
|
@ -2832,7 +2835,13 @@ namespace Microsoft.AspNetCore.Mvc.Core.Test
|
|||
private static ControllerBase GetController(IModelBinder binder, IValueProvider valueProvider)
|
||||
{
|
||||
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
|
||||
var httpContext = new DefaultHttpContext()
|
||||
{
|
||||
RequestServices = services.BuildServiceProvider()
|
||||
};
|
||||
|
||||
var validatorProviders = new[]
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -108,7 +109,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
modelBinderFactory,
|
||||
Mock.Of<IModelValidatorProvider>()),
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance),
|
||||
modelBinderFactory,
|
||||
modelMetadataProvider,
|
||||
filterProviders,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -1032,10 +1035,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
return Task.FromResult(result);
|
||||
});
|
||||
|
||||
var controllerContext = new ControllerContext
|
||||
{
|
||||
ActionDescriptor = actionDescriptor,
|
||||
};
|
||||
var controllerContext = GetControllerContext(actionDescriptor);
|
||||
|
||||
var arguments = new Dictionary<string, object>(StringComparer.Ordinal);
|
||||
var modelState = controllerContext.ModelState;
|
||||
|
|
@ -1063,10 +1063,16 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
|
||||
private static ControllerContext GetControllerContext(ControllerActionDescriptor descriptor = null)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
|
||||
var context = new ControllerContext()
|
||||
{
|
||||
ActionDescriptor = descriptor ?? GetActionDescriptor(),
|
||||
HttpContext = new DefaultHttpContext(),
|
||||
HttpContext = new DefaultHttpContext()
|
||||
{
|
||||
RequestServices = services.BuildServiceProvider()
|
||||
},
|
||||
RouteData = new RouteData(),
|
||||
};
|
||||
|
||||
|
|
@ -1140,7 +1146,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
return new ParameterBinder(
|
||||
modelMetadataProvider ?? TestModelMetadataProvider.CreateDefaultProvider(),
|
||||
factory,
|
||||
validatorProvider.Object);
|
||||
validatorProvider.Object,
|
||||
NullLoggerFactory.Instance);
|
||||
}
|
||||
|
||||
private static Mock<IModelValidator> CreateMockValidator()
|
||||
|
|
|
|||
|
|
@ -448,7 +448,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
: base(
|
||||
new EmptyModelMetadataProvider(),
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>())
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance)
|
||||
{
|
||||
_actionParameters = actionParameters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -27,7 +28,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
typeof(ModelWithIntArrayProperty),
|
||||
nameof(ModelWithIntArrayProperty.ArrayProperty));
|
||||
|
||||
var binder = new ArrayModelBinder<int>(new SimpleTypeModelBinder(typeof(int)));
|
||||
var binder = new ArrayModelBinder<int>(
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -43,7 +46,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task ArrayModelBinder_CreatesEmptyCollection_IfIsTopLevelObject()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new ArrayModelBinder<string>(new SimpleTypeModelBinder(typeof(string)));
|
||||
var binder = new ArrayModelBinder<string>(
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.IsTopLevelObject = true;
|
||||
|
|
@ -70,7 +75,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task ArrayModelBinder_DoesNotCreateCollection_IfNotIsTopLevelObject(string prefix)
|
||||
{
|
||||
// Arrange
|
||||
var binder = new ArrayModelBinder<string>(new SimpleTypeModelBinder(typeof(string)));
|
||||
var binder = new ArrayModelBinder<string>(
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = ModelNames.CreatePropertyModelName(prefix, "ArrayProperty");
|
||||
|
|
@ -126,7 +133,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
typeof(ModelWithIntArrayProperty),
|
||||
nameof(ModelWithIntArrayProperty.ArrayProperty));
|
||||
|
||||
var binder = new ArrayModelBinder<int>(new SimpleTypeModelBinder(typeof(int)));
|
||||
var binder = new ArrayModelBinder<int>(
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
|
|||
|
|
@ -648,8 +648,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
await binder.BindModelAsync(bindingContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal($"Rejected input formatter '{typeof(TestInputFormatter)}' for content type 'application/json'.", sink.Writes[0].State.ToString());
|
||||
Assert.Equal($"Selected input formatter '{typeof(TestInputFormatter)}' for content type 'application/json'.", sink.Writes[1].State.ToString());
|
||||
Assert.Equal($"Attempting to bind model of type '{typeof(Person)}' using the name 'someName' in request data ...", sink.Writes[0].State.ToString());
|
||||
Assert.Equal($"Rejected input formatter '{typeof(TestInputFormatter)}' for content type 'application/json'.", sink.Writes[1].State.ToString());
|
||||
Assert.Equal($"Selected input formatter '{typeof(TestInputFormatter)}' for content type 'application/json'.", sink.Writes[2].State.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -677,6 +678,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Assert
|
||||
Assert.Collection(
|
||||
sink.Writes,
|
||||
write => Assert.Equal(
|
||||
$"Attempting to bind model of type '{typeof(Person)}' using the name 'someName' in request data ...", write.State.ToString()),
|
||||
write => Assert.Equal(
|
||||
$"Rejected input formatter '{typeof(TestInputFormatter)}' for content type 'multipart/form-data'.", write.State.ToString()),
|
||||
write => Assert.Equal(
|
||||
|
|
@ -684,7 +687,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
write => Assert.Equal(
|
||||
"No input formatter was found to support the content type 'multipart/form-data' for use with the [FromBody] attribute.", write.State.ToString()),
|
||||
write => Assert.Equal(
|
||||
$"To use model binding, remove the [FromBody] attribute from the property or parameter named '{bindingContext.ModelName}' with model type '{bindingContext.ModelType}'.", write.State.ToString()));
|
||||
$"To use model binding, remove the [FromBody] attribute from the property or parameter named '{bindingContext.ModelName}' with model type '{bindingContext.ModelType}'.", write.State.ToString()),
|
||||
write => Assert.Equal(
|
||||
$"Done attempting to bind model of type '{typeof(Person)}' using the name 'someName'.", write.State.ToString()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -21,7 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
|
||||
var binder = new ByteArrayModelBinder();
|
||||
var binder = new ByteArrayModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -45,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
|
||||
var binder = new ByteArrayModelBinder();
|
||||
var binder = new ByteArrayModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -68,7 +69,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
|
||||
var binder = new ByteArrayModelBinder();
|
||||
var binder = new ByteArrayModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -90,7 +91,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(byte[]));
|
||||
var binder = new ByteArrayModelBinder();
|
||||
var binder = new ByteArrayModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -26,7 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "someName[baz]", "200" }
|
||||
};
|
||||
var bindingContext = GetModelBindingContext(valueProvider);
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var collectionResult = await binder.BindComplexCollectionFromIndexes(
|
||||
|
|
@ -52,7 +53,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "someName[3]", "400" }
|
||||
};
|
||||
var bindingContext = GetModelBindingContext(valueProvider);
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var boundCollection = await binder.BindComplexCollectionFromIndexes(bindingContext, indexNames: null);
|
||||
|
|
@ -79,7 +80,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
var bindingContext = GetModelBindingContext(valueProvider, isReadOnly);
|
||||
var modelState = bindingContext.ModelState;
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -110,7 +111,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var modelState = bindingContext.ModelState;
|
||||
var list = new List<int>();
|
||||
bindingContext.Model = list;
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -136,7 +137,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
var bindingContext = GetModelBindingContext(valueProvider, isReadOnly);
|
||||
var modelState = bindingContext.ModelState;
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -162,7 +163,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var modelState = bindingContext.ModelState;
|
||||
var list = new List<int>();
|
||||
bindingContext.Model = list;
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -178,7 +179,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task BindModelAsync_SimpleCollectionWithNullValue_Succeeds()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
var valueProvider = new SimpleValueProvider
|
||||
{
|
||||
{ "someName", null },
|
||||
|
|
@ -199,7 +200,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task BindSimpleCollection_RawValueIsEmptyCollection_ReturnsEmptyList()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
var context = GetModelBindingContext(new SimpleValueProvider());
|
||||
|
||||
// Act
|
||||
|
|
@ -214,7 +215,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task CollectionModelBinder_CreatesEmptyCollection_IfIsTopLevelObject()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new CollectionModelBinder<string>(new StubModelBinder(result: ModelBindingResult.Failed()));
|
||||
var binder = new CollectionModelBinder<string>(
|
||||
new StubModelBinder(result: ModelBindingResult.Failed()),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.IsTopLevelObject = true;
|
||||
|
|
@ -241,7 +244,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task CollectionModelBinder_DoesNotCreateEmptyCollection_IfModelNonNull()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new CollectionModelBinder<string>(new StubModelBinder(result: ModelBindingResult.Failed()));
|
||||
var binder = new CollectionModelBinder<string>(
|
||||
new StubModelBinder(result: ModelBindingResult.Failed()),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.IsTopLevelObject = true;
|
||||
|
|
@ -272,7 +277,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task CollectionModelBinder_DoesNotCreateCollection_IfNotIsTopLevelObject(string prefix)
|
||||
{
|
||||
// Arrange
|
||||
var binder = new CollectionModelBinder<string>(new StubModelBinder(result: ModelBindingResult.Failed()));
|
||||
var binder = new CollectionModelBinder<string>(
|
||||
new StubModelBinder(result: ModelBindingResult.Failed()),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = ModelNames.CreatePropertyModelName(prefix, "ListProperty");
|
||||
|
|
@ -313,7 +320,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public void CanCreateInstance_ReturnsExpectedValue(Type modelType, bool expectedResult)
|
||||
{
|
||||
// Arrange
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder());
|
||||
var binder = new CollectionModelBinder<int>(CreateIntBinder(), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var result = binder.CanCreateInstance(modelType);
|
||||
|
|
@ -335,7 +342,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
mbc.Result = ModelBindingResult.Success(42);
|
||||
});
|
||||
|
||||
var modelBinder = new CollectionModelBinder<int>(elementBinder);
|
||||
var modelBinder = new CollectionModelBinder<int>(elementBinder, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var boundCollection = await modelBinder.BindSimpleCollection(
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -1352,7 +1353,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
}
|
||||
|
||||
public TestableComplexTypeModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders)
|
||||
: base(propertyBinders)
|
||||
: base(propertyBinders, NullLoggerFactory.Instance)
|
||||
{
|
||||
Results = new Dictionary<ModelMetadata, ModelBindingResult>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
protected override IModelBinder GetBinder(NumberStyles numberStyles)
|
||||
{
|
||||
return new DecimalModelBinder(numberStyles);
|
||||
return new DecimalModelBinder(numberStyles, NullLoggerFactory.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -36,8 +37,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.ValueProvider = CreateEnumerableValueProvider("{0}", values);
|
||||
|
||||
var binder = new DictionaryModelBinder<int, string>(
|
||||
new SimpleTypeModelBinder(typeof(int)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -76,8 +78,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.Model = dictionary;
|
||||
|
||||
var binder = new DictionaryModelBinder<int, string>(
|
||||
new SimpleTypeModelBinder(typeof(int)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -132,8 +135,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var binder = new DictionaryModelBinder<string, string>(
|
||||
new SimpleTypeModelBinder(typeof(string)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = modelName;
|
||||
|
|
@ -168,8 +172,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
};
|
||||
|
||||
var binder = new DictionaryModelBinder<string, string>(
|
||||
new SimpleTypeModelBinder(typeof(string)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = "prefix";
|
||||
|
|
@ -218,8 +223,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var stringDictionary = dictionary.ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value.ToString());
|
||||
|
||||
var binder = new DictionaryModelBinder<long, int>(
|
||||
new SimpleTypeModelBinder(typeof(long)),
|
||||
new SimpleTypeModelBinder(typeof(int)));
|
||||
new SimpleTypeModelBinder(typeof(long), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = "prefix";
|
||||
|
|
@ -271,12 +277,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var valueMetadata = metadataProvider.GetMetadataForType(typeof(ModelWithProperties));
|
||||
|
||||
var binder = new DictionaryModelBinder<int, ModelWithProperties>(
|
||||
new SimpleTypeModelBinder(typeof(int)),
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
new ComplexTypeModelBinder(new Dictionary<ModelMetadata, IModelBinder>()
|
||||
{
|
||||
{ valueMetadata.Properties["Id"], new SimpleTypeModelBinder(typeof(int)) },
|
||||
{ valueMetadata.Properties["Name"], new SimpleTypeModelBinder(typeof(string)) },
|
||||
}));
|
||||
{ valueMetadata.Properties["Id"], new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance) },
|
||||
{ valueMetadata.Properties["Name"], new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance) },
|
||||
},
|
||||
NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -310,8 +318,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Arrange
|
||||
var expectedDictionary = new SortedDictionary<string, string>(dictionary);
|
||||
var binder = new DictionaryModelBinder<string, string>(
|
||||
new SimpleTypeModelBinder(typeof(string)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = modelName;
|
||||
|
|
@ -339,8 +348,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var binder = new DictionaryModelBinder<string, string>(
|
||||
new SimpleTypeModelBinder(typeof(string)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.IsTopLevelObject = true;
|
||||
|
|
@ -368,8 +378,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var binder = new DictionaryModelBinder<int, int>(
|
||||
new SimpleTypeModelBinder(typeof(int)),
|
||||
new SimpleTypeModelBinder(typeof(int)));
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = ModelNames.CreatePropertyModelName(prefix, "ListProperty");
|
||||
|
|
@ -412,8 +423,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var binder = new DictionaryModelBinder<int, int>(
|
||||
new SimpleTypeModelBinder(typeof(int)),
|
||||
new SimpleTypeModelBinder(typeof(int)));
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var result = binder.CanCreateInstance(modelType);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
protected override IModelBinder GetBinder(NumberStyles numberStyles)
|
||||
{
|
||||
return new DoubleModelBinder(numberStyles);
|
||||
return new DoubleModelBinder(numberStyles, NullLoggerFactory.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
protected override IModelBinder GetBinder(NumberStyles numberStyles)
|
||||
{
|
||||
return new FloatModelBinder(numberStyles);
|
||||
return new FloatModelBinder(numberStyles, NullLoggerFactory.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -26,7 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
});
|
||||
var httpContext = GetMockHttpContext(formCollection);
|
||||
var bindingContext = GetBindingContext(typeof(IFormCollection), httpContext);
|
||||
var binder = new FormCollectionModelBinder();
|
||||
var binder = new FormCollectionModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -47,7 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Arrange
|
||||
var httpContext = GetMockHttpContext(null, hasForm: false);
|
||||
var bindingContext = GetBindingContext(typeof(IFormCollection), httpContext);
|
||||
var binder = new FormCollectionModelBinder();
|
||||
var binder = new FormCollectionModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
formFiles.Add(GetMockFormFile("file", "file1.txt"));
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IEnumerable<IFormFile>), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -44,7 +45,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var formFiles = GetTwoFiles();
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IEnumerable<IFormFile>), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -73,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task FormFileModelBinder_BindsFiles_ForCollectionsItCanCreate(Type destinationType)
|
||||
{
|
||||
// Arrange
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
var formFiles = GetTwoFiles();
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(destinationType, httpContext);
|
||||
|
|
@ -94,7 +95,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var formFiles = GetTwoFiles();
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -112,7 +113,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var formFiles = new FormFileCollection();
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -130,7 +131,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
formFiles.Add(GetMockFormFile("different name", "file1.txt"));
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -156,7 +157,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.FieldName = "FieldName";
|
||||
bindingContext.ModelName = "ModelName";
|
||||
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -176,7 +177,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
formFiles.Add(new Mock<IFormFile>().Object);
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -194,7 +195,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
formFiles.Add(GetMockFormFile("file", ""));
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(IFormFile), httpContext);
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -208,7 +209,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task FormFileModelBinder_ReturnsResult_ForReadOnlyDestination()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
var formFiles = GetTwoFiles();
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContextForReadOnlyArray(httpContext);
|
||||
|
|
@ -225,7 +226,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task FormFileModelBinder_ReturnsFailedResult_ForCollectionsItCannotCreate()
|
||||
{
|
||||
// Arrange
|
||||
var binder = new FormFileModelBinder();
|
||||
var binder = new FormFileModelBinder(NullLoggerFactory.Instance);
|
||||
var formFiles = GetTwoFiles();
|
||||
var httpContext = GetMockHttpContext(GetMockFormCollection(formFiles));
|
||||
var bindingContext = GetBindingContext(typeof(ISet<IFormFile>), httpContext);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -21,7 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
public async Task BindModelAsync_ReturnsNonEmptyResult_ForAllTypes_WithHeaderBindingSource(Type type)
|
||||
{
|
||||
// Arrange
|
||||
var binder = new HeaderModelBinder();
|
||||
var binder = new HeaderModelBinder(NullLoggerFactory.Instance);
|
||||
var bindingContext = GetBindingContext(type);
|
||||
|
||||
// Act
|
||||
|
|
@ -38,7 +39,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var type = typeof(string[]);
|
||||
var header = "Accept";
|
||||
var headerValue = "application/json,text/json";
|
||||
var binder = new HeaderModelBinder();
|
||||
var binder = new HeaderModelBinder(NullLoggerFactory.Instance);
|
||||
var bindingContext = GetBindingContext(type);
|
||||
|
||||
bindingContext.FieldName = header;
|
||||
|
|
@ -59,7 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var type = typeof(string);
|
||||
var header = "User-Agent";
|
||||
var headerValue = "UnitTest";
|
||||
var binder = new HeaderModelBinder();
|
||||
var binder = new HeaderModelBinder(NullLoggerFactory.Instance);
|
||||
var bindingContext = GetBindingContext(type);
|
||||
|
||||
bindingContext.FieldName = header;
|
||||
|
|
@ -85,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Arrange
|
||||
var header = "Accept";
|
||||
var headerValue = "application/json,text/json";
|
||||
var binder = new HeaderModelBinder();
|
||||
var binder = new HeaderModelBinder(NullLoggerFactory.Instance);
|
||||
var bindingContext = GetBindingContext(destinationType);
|
||||
|
||||
bindingContext.FieldName = header;
|
||||
|
|
@ -106,7 +107,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Arrange
|
||||
var header = "Accept";
|
||||
var headerValue = "application/json,text/json";
|
||||
var binder = new HeaderModelBinder();
|
||||
var binder = new HeaderModelBinder(NullLoggerFactory.Instance);
|
||||
var bindingContext = GetBindingContextForReadOnlyArray();
|
||||
|
||||
bindingContext.FieldName = header;
|
||||
|
|
@ -126,7 +127,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
// Arrange
|
||||
var header = "Accept";
|
||||
var headerValue = "application/json,text/json";
|
||||
var binder = new HeaderModelBinder();
|
||||
var binder = new HeaderModelBinder(NullLoggerFactory.Instance);
|
||||
var bindingContext = GetBindingContext(typeof(ISet<string>));
|
||||
|
||||
bindingContext.FieldName = header;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -19,7 +20,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
// Create string binder to create the value but not the key.
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>));
|
||||
var binder = new KeyValuePairModelBinder<int, string>(CreateIntBinder(false), CreateStringBinder());
|
||||
var binder = new KeyValuePairModelBinder<int, string>(
|
||||
CreateIntBinder(false),
|
||||
CreateStringBinder(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -41,8 +45,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
// Create int binder to create the value but not the key.
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>));
|
||||
var binder = new KeyValuePairModelBinder<int, string>(CreateIntBinder(), CreateStringBinder(false));
|
||||
|
||||
var binder = new KeyValuePairModelBinder<int, string>(
|
||||
CreateIntBinder(),
|
||||
CreateStringBinder(false),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
||||
|
|
@ -64,7 +71,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
|
||||
// Create int binder to create the value but not the key.
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>));
|
||||
var binder = new KeyValuePairModelBinder<int, string>(CreateIntBinder(false), CreateStringBinder(false));
|
||||
var binder = new KeyValuePairModelBinder<int, string>(
|
||||
CreateIntBinder(false),
|
||||
CreateStringBinder(false),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -82,7 +92,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var valueProvider = new SimpleValueProvider();
|
||||
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>));
|
||||
var binder = new KeyValuePairModelBinder<int, string>(CreateIntBinder(), CreateStringBinder());
|
||||
var binder = new KeyValuePairModelBinder<int, string>(
|
||||
CreateIntBinder(),
|
||||
CreateStringBinder(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -120,7 +133,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var valueProvider = new SimpleValueProvider();
|
||||
|
||||
var bindingContext = GetBindingContext(valueProvider, typeof(KeyValuePair<int, string>));
|
||||
var binder = new KeyValuePairModelBinder<int, string>(innerBinder, innerBinder);
|
||||
var binder = new KeyValuePairModelBinder<int, string>(innerBinder, innerBinder, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var result = await binder.TryBindStrongModel<int>(bindingContext, innerBinder, "Key", "someName.Key");
|
||||
|
|
@ -135,8 +148,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var binder = new KeyValuePairModelBinder<string, string>(
|
||||
new SimpleTypeModelBinder(typeof(string)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.IsTopLevelObject = true;
|
||||
|
|
@ -165,8 +179,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var binder = new KeyValuePairModelBinder<string, string>(
|
||||
new SimpleTypeModelBinder(typeof(string)),
|
||||
new SimpleTypeModelBinder(typeof(string)));
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var bindingContext = CreateContext();
|
||||
bindingContext.ModelName = ModelNames.CreatePropertyModelName(prefix, "KeyValuePairProperty");
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
|
|
@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", value }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(string));
|
||||
var binder = new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -53,7 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
.DisplayDetails(d => d.ConvertEmptyStringToNull = false);
|
||||
bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(typeof(string));
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(string));
|
||||
var binder = new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -99,7 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "some-value" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(destinationType);
|
||||
var binder = new SimpleTypeModelBinder(destinationType, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -118,7 +119,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
{ "theModelName", string.Empty }
|
||||
};
|
||||
var binder = new SimpleTypeModelBinder(destinationType);
|
||||
var binder = new SimpleTypeModelBinder(destinationType, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -143,7 +144,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "not an integer" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(int));
|
||||
var binder = new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -161,7 +162,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{
|
||||
// Arrange
|
||||
var bindingContext = GetBindingContext(typeof(int));
|
||||
var binder = new SimpleTypeModelBinder(typeof(int));
|
||||
var binder = new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -183,7 +184,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", value }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(string));
|
||||
var binder = new SimpleTypeModelBinder(typeof(string), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -203,7 +204,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "12" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(int?));
|
||||
var binder = new SimpleTypeModelBinder(typeof(int?), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -224,7 +225,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "12.5" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(double?));
|
||||
var binder = new SimpleTypeModelBinder(typeof(double?), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -245,7 +246,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "42" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(int));
|
||||
var binder = new SimpleTypeModelBinder(typeof(int), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -287,7 +288,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "32,000" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(type);
|
||||
var binder = new SimpleTypeModelBinder(type, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -315,7 +316,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "12,5" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(decimal));
|
||||
var binder = new SimpleTypeModelBinder(typeof(decimal), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -336,7 +337,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", "12,5" }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(decimal));
|
||||
var binder = new SimpleTypeModelBinder(typeof(decimal), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -360,7 +361,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", new object[] { "Value1" } }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(IntEnum));
|
||||
var binder = new SimpleTypeModelBinder(typeof(IntEnum), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -381,7 +382,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", new object[] { "1" } }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(IntEnum));
|
||||
var binder = new SimpleTypeModelBinder(typeof(IntEnum), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -422,7 +423,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", flagsEnumValue }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(IntEnum));
|
||||
var binder = new SimpleTypeModelBinder(typeof(IntEnum), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
@ -445,7 +446,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
{ "theModelName", flagsEnumValue }
|
||||
};
|
||||
|
||||
var binder = new SimpleTypeModelBinder(typeof(FlagsEnum));
|
||||
var binder = new SimpleTypeModelBinder(typeof(FlagsEnum), NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await binder.BindModelAsync(bindingContext);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -73,7 +76,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
|
||||
// Act
|
||||
var context = DefaultModelBindingContext.CreateBindingContext(
|
||||
new ActionContext(),
|
||||
GetActionContext(),
|
||||
original,
|
||||
metadataProvider.GetMetadataForType(typeof(object)),
|
||||
new BindingInfo() { BindingSource = BindingSource.Query },
|
||||
|
|
@ -96,7 +99,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
|
||||
var original = CreateDefaultValueProvider();
|
||||
var context = DefaultModelBindingContext.CreateBindingContext(
|
||||
new ActionContext(),
|
||||
GetActionContext(),
|
||||
original,
|
||||
metadataProvider.GetMetadataForType(typeof(string)),
|
||||
new BindingInfo(),
|
||||
|
|
@ -125,7 +128,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var original = CreateDefaultValueProvider();
|
||||
|
||||
var context = DefaultModelBindingContext.CreateBindingContext(
|
||||
new ActionContext(),
|
||||
GetActionContext(),
|
||||
original,
|
||||
metadataProvider.GetMetadataForType(typeof(string)),
|
||||
new BindingInfo() { BindingSource = BindingSource.Query },
|
||||
|
|
@ -155,6 +158,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
Assert.Equal(typeof(int), bindingContext.ModelType);
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
|
||||
return new ActionContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext()
|
||||
{
|
||||
RequestServices = services.BuildServiceProvider()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static CompositeValueProvider CreateDefaultValueProvider()
|
||||
{
|
||||
var result = new CompositeValueProvider();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using System;
|
|||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -21,7 +24,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
$"empty. At least one '{typeof(IModelBinderProvider).FullName}' is required to model bind.";
|
||||
var metadataProvider = new TestModelMetadataProvider();
|
||||
var options = Options.Create(new MvcOptions());
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
Metadata = metadataProvider.GetMetadataForType(typeof(string)),
|
||||
|
|
@ -40,7 +46,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var options = Options.Create(new MvcOptions());
|
||||
options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(_ => null));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
Metadata = metadataProvider.GetMetadataForType(typeof(string)),
|
||||
|
|
@ -72,7 +81,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return null;
|
||||
}));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -95,7 +107,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
.ForProperty<Widget>(nameof(Widget.Id))
|
||||
.BindingDetails(m => m.IsBindingAllowed = false);
|
||||
|
||||
var modelBinder = new ByteArrayModelBinder();
|
||||
var modelBinder = new ByteArrayModelBinder(NullLoggerFactory.Instance);
|
||||
|
||||
var options = Options.Create(new MvcOptions());
|
||||
options.Value.ModelBinderProviders.Add(new TestModelBinderProvider(c =>
|
||||
|
|
@ -108,7 +120,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return null;
|
||||
}));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -145,7 +160,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return null;
|
||||
}));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -182,7 +200,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return Mock.Of<IModelBinder>();
|
||||
}));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -209,7 +230,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return Mock.Of<IModelBinder>();
|
||||
}));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -237,7 +261,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return Mock.Of<IModelBinder>();
|
||||
}));
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -345,7 +372,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var options = Options.Create(new MvcOptions());
|
||||
options.Value.ModelBinderProviders.Insert(0, modelBinderProvider);
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
var factoryContext = new ModelBinderFactoryContext
|
||||
{
|
||||
BindingInfo = parameterBindingInfo,
|
||||
|
|
@ -398,7 +428,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
options.Value.ModelBinderProviders.Add(widgetProvider);
|
||||
options.Value.ModelBinderProviders.Add(widgetIdProvider);
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -457,7 +490,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
options.Value.ModelBinderProviders.Add(widgetProvider);
|
||||
options.Value.ModelBinderProviders.Add(widgetIdProvider);
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -508,7 +544,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
options.Value.ModelBinderProviders.Add(widgetProvider);
|
||||
options.Value.ModelBinderProviders.Add(widgetIdProvider);
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -569,7 +608,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
options.Value.ModelBinderProviders.Add(widgetProvider);
|
||||
options.Value.ModelBinderProviders.Add(widgetIdProvider);
|
||||
|
||||
var factory = new ModelBinderFactory(metadataProvider, options);
|
||||
var factory = new ModelBinderFactory(
|
||||
metadataProvider,
|
||||
options,
|
||||
GetServices());
|
||||
|
||||
var context = new ModelBinderFactoryContext()
|
||||
{
|
||||
|
|
@ -597,6 +639,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
Assert.Equal(0, widgetIdProvider.SuccessCount);
|
||||
}
|
||||
|
||||
private IServiceProvider GetServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
private class Widget
|
||||
{
|
||||
public WidgetId Id { get; set; }
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -36,7 +39,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
string.Empty,
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binder),
|
||||
Mock.Of<IValueProvider>(),
|
||||
|
|
@ -70,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var valueProvider = new TestValueProvider(values);
|
||||
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
||||
|
||||
var actionContext = new ActionContext() { HttpContext = new DefaultHttpContext() };
|
||||
var actionContext = GetActionContext();
|
||||
var modelState = actionContext.ModelState;
|
||||
|
||||
// Act
|
||||
|
|
@ -117,7 +120,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binderProviders),
|
||||
valueProvider,
|
||||
|
|
@ -141,7 +144,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
string.Empty,
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binder),
|
||||
Mock.Of<IValueProvider>(),
|
||||
|
|
@ -195,7 +198,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binderProviders),
|
||||
valueProvider,
|
||||
|
|
@ -221,7 +224,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
string.Empty,
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binder),
|
||||
Mock.Of<IValueProvider>(),
|
||||
|
|
@ -271,7 +274,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
TestModelMetadataProvider.CreateDefaultProvider(),
|
||||
GetModelBinderFactory(binderProviders),
|
||||
valueProvider,
|
||||
|
|
@ -322,7 +325,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var result = await ModelBindingHelper.TryUpdateModelAsync(
|
||||
model,
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binderProviders),
|
||||
valueProvider,
|
||||
|
|
@ -469,7 +472,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
model,
|
||||
model.GetType(),
|
||||
prefix: "",
|
||||
actionContext: new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
actionContext: GetActionContext(),
|
||||
metadataProvider: metadataProvider,
|
||||
modelBinderFactory: GetModelBinderFactory(binder),
|
||||
valueProvider: Mock.Of<IValueProvider>(),
|
||||
|
|
@ -524,7 +527,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
model,
|
||||
model.GetType(),
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binderProviders),
|
||||
valueProvider,
|
||||
|
|
@ -552,7 +555,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
model,
|
||||
modelType: model.GetType(),
|
||||
prefix: "",
|
||||
actionContext: new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
actionContext: GetActionContext(),
|
||||
metadataProvider: metadataProvider,
|
||||
modelBinderFactory: GetModelBinderFactory(binder.Object),
|
||||
valueProvider: Mock.Of<IValueProvider>(),
|
||||
|
|
@ -592,7 +595,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
model,
|
||||
model.GetType(),
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binderProviders),
|
||||
valueProvider,
|
||||
|
|
@ -623,7 +626,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
model,
|
||||
typeof(User),
|
||||
"",
|
||||
new ActionContext() { HttpContext = new DefaultHttpContext() },
|
||||
GetActionContext(),
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(binder.Object),
|
||||
Mock.Of<IValueProvider>(),
|
||||
|
|
@ -1492,6 +1495,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
Assert.False(result);
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
|
||||
return new ActionContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext()
|
||||
{
|
||||
RequestServices = services.BuildServiceProvider()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static DefaultModelBindingContext GetBindingContextForProperty(string propertyName)
|
||||
{
|
||||
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
||||
|
|
|
|||
|
|
@ -5,12 +5,16 @@ using System;
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -94,9 +98,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var parameterBinder = new ParameterBinder(
|
||||
metadataProvider,
|
||||
factory.Object,
|
||||
CreateMockValidatorProvider());
|
||||
CreateMockValidatorProvider(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var controllerContext = new ControllerContext();
|
||||
var controllerContext = GetControllerContext();
|
||||
|
||||
// Act & Assert
|
||||
await parameterBinder.BindModelAsync(controllerContext, new SimpleValueProvider(), parameterDescriptor);
|
||||
|
|
@ -144,7 +149,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
var argumentBinder = new ParameterBinder(
|
||||
metadataProvider,
|
||||
factory.Object,
|
||||
CreateMockValidatorProvider());
|
||||
CreateMockValidatorProvider(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var valueProvider = new SimpleValueProvider
|
||||
{
|
||||
|
|
@ -152,7 +158,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
};
|
||||
var valueProviderFactory = new SimpleValueProviderFactory(valueProvider);
|
||||
|
||||
var controllerContext = new ControllerContext();
|
||||
var controllerContext = GetControllerContext();
|
||||
|
||||
// Act & Assert
|
||||
await argumentBinder.BindModelAsync(controllerContext, valueProvider, parameterDescriptor);
|
||||
|
|
@ -163,7 +169,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
public async Task BindModelAsync_EnforcesTopLevelBindRequired()
|
||||
{
|
||||
// Arrange
|
||||
var actionContext = new ControllerContext();
|
||||
var actionContext = GetControllerContext();
|
||||
|
||||
var mockModelMetadata = CreateMockModelMetadata();
|
||||
mockModelMetadata.Setup(o => o.IsBindingRequired).Returns(true);
|
||||
|
|
@ -193,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
public async Task BindModelAsync_EnforcesTopLevelRequired()
|
||||
{
|
||||
// Arrange
|
||||
var actionContext = new ControllerContext();
|
||||
var actionContext = GetControllerContext();
|
||||
var mockModelMetadata = CreateMockModelMetadata();
|
||||
mockModelMetadata.Setup(o => o.IsRequired).Returns(true);
|
||||
mockModelMetadata.Setup(o => o.DisplayName).Returns("My Display Name");
|
||||
|
|
@ -233,7 +239,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
public async Task BindModelAsync_EnforcesTopLevelDataAnnotationsAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var actionContext = new ControllerContext();
|
||||
var actionContext = GetControllerContext();
|
||||
var mockModelMetadata = CreateMockModelMetadata();
|
||||
var validationAttribute = new RangeAttribute(1, 100);
|
||||
mockModelMetadata.Setup(o => o.DisplayName).Returns("My Display Name");
|
||||
|
|
@ -272,7 +278,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
public async Task BindModelAsync_SupportsIObjectModelValidatorForBackCompat()
|
||||
{
|
||||
// Arrange
|
||||
var actionContext = new ControllerContext();
|
||||
var actionContext = GetControllerContext();
|
||||
|
||||
var mockValidator = new Mock<IObjectModelValidator>(MockBehavior.Strict);
|
||||
mockValidator
|
||||
|
|
@ -309,6 +315,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
actionContext.ModelState.Single().Value.Errors.Single().ErrorMessage);
|
||||
}
|
||||
|
||||
private static ControllerContext GetControllerContext()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
|
||||
return new ControllerContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext()
|
||||
{
|
||||
RequestServices = services.BuildServiceProvider()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Mock<FakeModelMetadata> CreateMockModelMetadata()
|
||||
{
|
||||
var mockModelMetadata = new Mock<FakeModelMetadata>();
|
||||
|
|
@ -344,7 +364,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return new ParameterBinder(
|
||||
mockModelMetadataProvider.Object,
|
||||
mockModelBinderFactory.Object,
|
||||
CreateMockValidatorProvider(validator));
|
||||
CreateMockValidatorProvider(validator),
|
||||
NullLoggerFactory.Instance);
|
||||
}
|
||||
|
||||
private static ParameterBinder CreateBackCompatParameterBinder(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||
{
|
||||
|
|
@ -25,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
BindingSource = Metadata.BindingSource,
|
||||
PropertyFilterProvider = Metadata.PropertyFilterProvider,
|
||||
};
|
||||
|
||||
Services = GetServices();
|
||||
}
|
||||
|
||||
public TestModelBinderProviderContext(ModelMetadata metadata, BindingInfo bindingInfo)
|
||||
|
|
@ -40,6 +43,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
};
|
||||
|
||||
MetadataProvider = CachedMetadataProvider;
|
||||
Services = GetServices();
|
||||
}
|
||||
|
||||
public override BindingInfo BindingInfo { get; }
|
||||
|
|
@ -48,6 +52,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
|
||||
public override IModelMetadataProvider MetadataProvider { get; }
|
||||
|
||||
public override IServiceProvider Services { get; }
|
||||
|
||||
public override IModelBinder CreateBinder(ModelMetadata metadata)
|
||||
{
|
||||
foreach (var creator in _binderCreators)
|
||||
|
|
@ -71,5 +77,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
{
|
||||
_binderCreators.Add((m) => m.Equals(metadata) ? binderCreator() : null);
|
||||
}
|
||||
|
||||
private static IServiceProvider GetServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
||||
|
|
@ -757,7 +758,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
|||
private class CustomComplexTypeModelBinder : ComplexTypeModelBinder
|
||||
{
|
||||
public CustomComplexTypeModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders)
|
||||
: base(propertyBinders)
|
||||
: base(propertyBinders, NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
|||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
|
@ -77,19 +78,22 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
|||
return new ParameterBinder(
|
||||
metadataProvider,
|
||||
GetModelBinderFactory(metadataProvider, options),
|
||||
new CompositeModelValidatorProvider(GetModelValidatorProviders(options)));
|
||||
new CompositeModelValidatorProvider(GetModelValidatorProviders(options)),
|
||||
NullLoggerFactory.Instance);
|
||||
}
|
||||
|
||||
public static IModelBinderFactory GetModelBinderFactory(
|
||||
IModelMetadataProvider metadataProvider,
|
||||
IOptions<MvcOptions> options = null)
|
||||
{
|
||||
var services = GetServices();
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
options = GetServices().GetRequiredService<IOptions<MvcOptions>>();
|
||||
options = services.GetRequiredService<IOptions<MvcOptions>>();
|
||||
}
|
||||
|
||||
return new ModelBinderFactory(metadataProvider, options);
|
||||
return new ModelBinderFactory(metadataProvider, options, services);
|
||||
}
|
||||
|
||||
public static IObjectModelValidator GetObjectValidator(
|
||||
|
|
|
|||
|
|
@ -479,7 +479,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var parameterBinder = new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
return new PageActionInvokerProvider(
|
||||
loader,
|
||||
|
|
|
|||
|
|
@ -1238,7 +1238,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
return new ParameterBinder(
|
||||
TestModelMetadataProvider.CreateDefaultProvider(),
|
||||
factory,
|
||||
validator);
|
||||
validator,
|
||||
NullLoggerFactory.Instance);
|
||||
}
|
||||
|
||||
private static IModelValidatorProvider CreateMockValidatorProvider()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -29,7 +32,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var binder = new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);
|
||||
|
|
@ -52,7 +56,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var binder = new ParameterBinder(
|
||||
TestModelMetadataProvider.CreateDefaultProvider(),
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);
|
||||
|
|
@ -73,7 +78,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var binder = new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);
|
||||
|
|
@ -95,7 +101,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var binder = new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);
|
||||
|
|
@ -116,7 +123,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var binder = new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);
|
||||
|
|
@ -138,7 +146,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var binder = new ParameterBinder(
|
||||
modelMetadataProvider,
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>());
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
var factory = PagePropertyBinderFactory.CreateBinder(binder, modelMetadataProvider, actionDescriptor);
|
||||
|
|
@ -155,7 +164,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
var actionDescriptor = new CompiledPageActionDescriptor
|
||||
{
|
||||
BoundProperties = new []
|
||||
BoundProperties = new[]
|
||||
{
|
||||
new PageBoundPropertyDescriptor()
|
||||
{
|
||||
|
|
@ -192,10 +201,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
var page = new PageWithProperty
|
||||
{
|
||||
PageContext = new PageContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext(),
|
||||
},
|
||||
PageContext = GetPageContext(),
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -253,10 +259,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
var page = new PageWithProperty
|
||||
{
|
||||
PageContext = new PageContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext(),
|
||||
}
|
||||
PageContext = GetPageContext()
|
||||
};
|
||||
|
||||
var model = new PageModelWithProperty();
|
||||
|
|
@ -304,10 +307,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
var page = new PageWithProperty
|
||||
{
|
||||
PageContext = new PageContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext(),
|
||||
}
|
||||
PageContext = GetPageContext()
|
||||
};
|
||||
|
||||
var model = new PageModelWithDefaultValue();
|
||||
|
|
@ -368,16 +368,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
var page = new PageWithProperty
|
||||
{
|
||||
PageContext = new PageContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext()
|
||||
{
|
||||
Request=
|
||||
{
|
||||
Method = method,
|
||||
}
|
||||
}
|
||||
}
|
||||
PageContext = GetPageContext(method)
|
||||
};
|
||||
|
||||
var model = new PageModelWithSupportsGetProperty();
|
||||
|
|
@ -434,10 +425,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
var page = new PageWithProperty
|
||||
{
|
||||
PageContext = new PageContext()
|
||||
{
|
||||
HttpContext = new DefaultHttpContext(),
|
||||
}
|
||||
PageContext = GetPageContext()
|
||||
};
|
||||
|
||||
page.HttpContext.Request.Method = "Post";
|
||||
|
|
@ -452,6 +440,27 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Equal("value", model.Default);
|
||||
}
|
||||
|
||||
private PageContext GetPageContext(string httpMethod = null)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
|
||||
var httpContext = new DefaultHttpContext()
|
||||
{
|
||||
RequestServices = services.BuildServiceProvider()
|
||||
};
|
||||
|
||||
if (httpMethod != null)
|
||||
{
|
||||
httpContext.Request.Method = httpMethod;
|
||||
}
|
||||
|
||||
return new PageContext()
|
||||
{
|
||||
HttpContext = httpContext
|
||||
};
|
||||
}
|
||||
|
||||
private class TestParameterBinder : ParameterBinder
|
||||
{
|
||||
private readonly IDictionary<string, object> _args;
|
||||
|
|
@ -460,7 +469,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
: base(
|
||||
TestModelMetadataProvider.CreateDefaultProvider(),
|
||||
TestModelBinderFactory.CreateDefault(),
|
||||
Mock.Of<IModelValidatorProvider>())
|
||||
Mock.Of<IModelValidatorProvider>(),
|
||||
NullLoggerFactory.Instance)
|
||||
{
|
||||
_args = args;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="$(MicrosoftAspNetCoreHtmlAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Runtime" Version="$(MicrosoftAspNetCoreRazorRuntimePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="$(MicrosoftExtensionsFileProvidersAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.WebEncoders" Version="$(MicrosoftExtensionsWebEncodersPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
||||
{
|
||||
|
|
@ -36,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
}
|
||||
|
||||
public static TestModelBinderFactory CreateDefault(
|
||||
IModelMetadataProvider metadataProvider,
|
||||
IModelMetadataProvider metadataProvider,
|
||||
params IModelBinderProvider[] providers)
|
||||
{
|
||||
if (metadataProvider == null)
|
||||
|
|
@ -53,9 +57,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
return new TestModelBinderFactory(metadataProvider, options);
|
||||
}
|
||||
|
||||
protected TestModelBinderFactory(IModelMetadataProvider metadataProvider, IOptions<MvcOptions> options)
|
||||
: base(metadataProvider, options)
|
||||
protected TestModelBinderFactory(IModelMetadataProvider metadataProvider, IOptions<MvcOptions> options)
|
||||
: base(metadataProvider, options, GetServices())
|
||||
{
|
||||
}
|
||||
|
||||
private static IServiceProvider GetServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue