public async Task BindModelAsync_CreatesDataSetForParameter(string methodName, string paramName)
        {
            // Arrange
            var metadata       = GetMetadataForParameter(typeof(DataSetModelBinderTest), methodName);
            var bindingContext = new DefaultModelBindingContext
            {
                IsTopLevelObject = true,
                ModelMetadata    = metadata,
                ModelName        = paramName,
                FieldName        = paramName,
                ValueProvider    = new TestValueProvider(new Dictionary <string, object>()),
                ModelState       = new ModelStateDictionary()
            };

            var binder = new DataSetModelBinder <Student>(NullLoggerFactory.Instance);

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            Assert.True(bindingContext.Result.IsModelSet);
            Assert.NotNull(bindingContext.Result.Model);
            Assert.IsAssignableFrom <DataSet <Student> >(bindingContext.Result.Model);
            var keyValuePair = Assert.Single(bindingContext.ModelState);

            Assert.Equal(paramName, keyValuePair.Key);
            Assert.Empty(keyValuePair.Value.Errors);
        }
        public async Task BindModelAsync_ScalarDataSetParam()
        {
            // Arrange
            var metadata = GetMetadataForParameter(typeof(DataSetModelBinderTest), nameof(ActionWithScalarDataSetParameter));
            var values   = new Dictionary <string, object>()
            {
                { "StudentId", "1" },
                { "Name", "John" },
                { "Courses[0].CourseId", "1" },
                { "Courses[0].Name", "Math" },
                { "Courses[1].CourseId", "2" },
                { "Courses[1].Name", "History" }
            };
            var bindingContext = new DefaultModelBindingContext
            {
                IsTopLevelObject = true,
                ModelMetadata    = metadata,
                ModelName        = string.Empty,
                ValueProvider    = new TestValueProvider(values),
                ModelState       = new ModelStateDictionary()
            };

            var binder = new DataSetModelBinder <Student>(NullLoggerFactory.Instance);

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            var result       = (DataSet <Student>)bindingContext.Model;
            var expectedJson =
                @"[
   {
      ""StudentId"" : 1,
      ""Name"" : ""John"",
      ""Courses"" : [
         {
            ""CourseId"" : 1,
            ""Name"" : ""Math""
         },
         {
            ""CourseId"" : 2,
            ""Name"" : ""History""
         }
      ]
   }
]";

            Assert.Equal(expectedJson, result.ToJsonString(true));
        }
        public async Task BindModelAsync_ScalarDataSetParam_NoData()
        {
            // Arrange
            var metadata       = GetMetadataForParameter(typeof(DataSetModelBinderTest), nameof(ActionWithScalarDataSetParameter));
            var values         = new Dictionary <string, object>();
            var bindingContext = new DefaultModelBindingContext
            {
                IsTopLevelObject = true,
                ModelMetadata    = metadata,
                ModelName        = string.Empty,
                ValueProvider    = new TestValueProvider(values),
                ModelState       = new ModelStateDictionary()
            };

            var binder = new DataSetModelBinder <Student>(NullLoggerFactory.Instance);

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            var result = (DataSet <Student>)bindingContext.Model;

            Assert.Single(result);
        }
        public async Task BindModelAsync_CollectionDataSetParam_ExplicitIndex()
        {
            // Arrange
            var metadata  = GetMetadataForParameter(typeof(DataSetModelBinderTest), nameof(ActionWithDataSetParameter));
            var paramName = "parameter";

            var formCollection = new FormCollection(
                new Dictionary <string, StringValues>()
            {
                { "parameter.index", new string[] { "0", "2" } },
                { "parameter[0].StudentId", "1" },
                { "parameter[0].Name", "John" },
                { "parameter[0].Courses[0].CourseId", "1" },
                { "parameter[0].Courses[0].Name", "Math" },
                { "parameter[0].Courses[1].CourseId", "2" },
                { "parameter[0].Courses[1].Name", "History" },
                { "parameter[2].StudentId", "2" },
                { "parameter[2].Name", "Tony" },
                { "parameter[2].Courses[0].CourseId", "2" },
                { "parameter[2].Courses[0].Name", "History" },
                { "parameter[2].Courses[1].CourseId", "2" },
                { "parameter[2].Courses[1].Name", "Math" },
            });
            var vp             = new FormValueProvider(BindingSource.Form, formCollection, CultureInfo.CurrentCulture);
            var bindingContext = new DefaultModelBindingContext
            {
                IsTopLevelObject = true,
                ModelMetadata    = metadata,
                ModelName        = paramName,
                FieldName        = paramName,
                ValueProvider    = vp,
                ModelState       = new ModelStateDictionary()
            };

            var binder = new DataSetModelBinder <Student>(NullLoggerFactory.Instance);

            // Act
            await binder.BindModelAsync(bindingContext);

            // Assert
            var result       = (DataSet <Student>)bindingContext.Model;
            var expectedJson =
                @"[
   {
      ""StudentId"" : 1,
      ""Name"" : ""John"",
      ""Courses"" : [
         {
            ""CourseId"" : 1,
            ""Name"" : ""Math""
         },
         {
            ""CourseId"" : 2,
            ""Name"" : ""History""
         }
      ]
   },
   {
      ""StudentId"" : 2,
      ""Name"" : ""Tony"",
      ""Courses"" : [
         {
            ""CourseId"" : 2,
            ""Name"" : ""History""
         },
         {
            ""CourseId"" : 2,
            ""Name"" : ""Math""
         }
      ]
   }
]";

            Assert.Equal(expectedJson, result.ToJsonString(true));
        }