Beispiel #1
0
    private void EnforceBindRequiredAndValidate(
        ObjectModelValidator baseObjectValidator,
        ActionContext actionContext,
        ParameterDescriptor parameter,
        ModelMetadata metadata,
        ModelBindingContext modelBindingContext,
        ModelBindingResult modelBindingResult,
        object?container)
    {
        RecalculateModelMetadata(parameter, modelBindingResult, ref metadata);

        if (!modelBindingResult.IsModelSet && metadata.IsBindingRequired)
        {
            // Enforce BindingBehavior.Required (e.g., [BindRequired])
            var modelName = modelBindingContext.FieldName;
            var message   = metadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(modelName);
            actionContext.ModelState.TryAddModelError(modelName, message);
        }
        else if (modelBindingResult.IsModelSet)
        {
            // Enforce any other validation rules
            baseObjectValidator.Validate(
                actionContext,
                modelBindingContext.ValidationState,
                modelBindingContext.ModelName,
                modelBindingResult.Model,
                metadata,
                container);
        }
        else if (metadata.IsRequired)
        {
            // We need to special case the model name for cases where a 'fallback' to empty
            // prefix occurred but binding wasn't successful. For these cases there will be no
            // entry in validation state to match and determine the correct key.
            //
            // See https://github.com/aspnet/Mvc/issues/7503
            //
            // This is to avoid adding validation errors for an 'empty' prefix when a simple
            // type fails to bind. The fix for #7503 uncovered this issue, and was likely the
            // original problem being worked around that regressed #7503.
            var modelName = modelBindingContext.ModelName;

            if (string.IsNullOrEmpty(modelBindingContext.ModelName) &&
                parameter.BindingInfo?.BinderModelName == null)
            {
                // If we get here then this is a fallback case. The model name wasn't explicitly set
                // and we ended up with an empty prefix.
                modelName = modelBindingContext.FieldName;
            }

            // Run validation, we expect this to validate [Required].
            baseObjectValidator.Validate(
                actionContext,
                modelBindingContext.ValidationState,
                modelName,
                modelBindingResult.Model,
                metadata,
                container);
        }
    }
Beispiel #2
0
    public static ParameterBinder GetParameterBinder(
        IModelMetadataProvider metadataProvider,
        IModelBinderProvider binderProvider = null,
        MvcOptions mvcOptions          = null,
        ObjectModelValidator validator = null)
    {
        var services = GetServices(metadataProvider, mvcOptions: mvcOptions);
        var options  = services.GetRequiredService <IOptions <MvcOptions> >();

        if (binderProvider != null)
        {
            options.Value.ModelBinderProviders.Insert(0, binderProvider);
        }

        validator ??= new DefaultObjectValidator(
            metadataProvider,
            new[] { new CompositeModelValidatorProvider(GetModelValidatorProviders(options)) },
            options.Value);

        return(new ParameterBinder(
                   metadataProvider,
                   new ModelBinderFactory(metadataProvider, options, services),
                   validator,
                   options,
                   NullLoggerFactory.Instance));
    }