/// <summary>
        /// Processes an input object's attribute validation items.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns>InputModelStateEntry.</returns>
        private InputModelStateEntry ValidateSingleArgument(ExecutionArgument input)
        {
            var entry = new InputModelStateEntry(input);

            if (input.Value == null || input.Argument.ArgumentModifiers.IsSourceParameter())
            {
                entry.ValidationState = InputModelValidationState.Skipped;
                return(entry);
            }

            if (input.Argument.TypeExpression.IsListOfItems)
            {
                if (!(input.Value is IEnumerable enumerable))
                {
                    // given the common pipeline validation this scenario is impossible
                    // (the plan generator would have caught this during query validation)
                    entry.ValidationState = InputModelValidationState.Invalid;
                    entry.AddErrorMessage("Argument should be a list.");
                }
                else
                {
                    foreach (var item in enumerable)
                    {
                        this.ValidateSingleItem(entry, item);
                    }
                }
            }
        public async Task BadRequest_WithModelDictionary_RendersMessageOnResponse()
        {
            var server         = new TestServerBuilder().Build();
            var methodTemplate = TemplateHelper.CreateFieldTemplate <ActionableController>(nameof(ActionableController.DoStuff));
            var argTemplate    = methodTemplate.Arguments[0];
            var fieldArg       = new GraphArgumentMaker(server.Schema).CreateArgument(argTemplate).Argument;

            // name is marked required, will fail
            var dataItem = new ActionableModelItem()
            {
                Name = null,
                Id   = "5",
            };

            var arg = new ExecutionArgument(fieldArg, dataItem);
            var col = new ExecutionArgumentCollection();

            col.Add(arg);

            var generator       = new ModelStateGenerator();
            var modelDictionary = generator.CreateStateDictionary(col);

            var actionResult = new BadRequestGraphActionResult(modelDictionary);

            var context = this.CreateResolutionContext();
            await actionResult.Complete(context);

            Assert.IsNull(context.Result);
            Assert.IsTrue(context.Messages.Any(x => x.Code == Constants.ErrorCodes.BAD_REQUEST));
            Assert.IsTrue(context.Messages.Any(x => x.Code == Constants.ErrorCodes.MODEL_VALIDATION_ERROR));
        }
        /// <summary>
        /// Creates the state dictionary containing all the attribute base validation results for the provided arguments.
        /// </summary>
        /// <param name="argument">The argument to validate.</param>
        /// <returns>InputModelStateDictionary.</returns>
        public InputModelStateDictionary CreateStateDictionary(ExecutionArgument argument)
        {
            var dictionary = new InputModelStateDictionary();
            var entry      = this.ValidateSingleArgument(argument);

            dictionary.Add(entry);

            return(dictionary);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="InputModelStateEntry"/> class.
 /// </summary>
 /// <param name="inputArgument">The input argument.</param>
 public InputModelStateEntry(ExecutionArgument inputArgument)
 {
     this.Model           = Validation.ThrowIfNullOrReturn(inputArgument, nameof(inputArgument));
     this.ValidationState = InputModelValidationState.Unvalidated;
     this.Errors          = new List <InputModelError>();
 }