public async Task ModelMetadataType_ValidArray_NoModelStateErrors() { // Arrange var input = "[" + "{ \"Name\": \"MVC\", \"Contact\":\"4258959019\", \"Category\":\"Technology\"," + "\"CompanyName\":\"Microsoft\", \"Country\":\"USA\",\"Price\": 21, " + "\"ProductDetails\": {\"Detail1\": \"d1\", \"Detail2\": \"d2\", \"Detail3\": \"d3\"}}," + "{ \"Name\": \"MVC too\", \"Contact\":\"4258959020\", \"Category\":\"Technology\"," + "\"CompanyName\":\"Microsoft\", \"Country\":\"USA\",\"Price\": 22, " + "\"ProductDetails\": {\"Detail1\": \"d2\", \"Detail2\": \"d3\", \"Detail3\": \"d4\"}}" + "]"; var argumentBinding = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "Parameter1", ParameterType = typeof(IEnumerable <ProductViewModel>), BindingInfo = new BindingInfo { BindingSource = BindingSource.Body, }, }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(input)); request.ContentType = "application/json;charset=utf-8"; }); var modelState = testContext.ModelState; // Act var result = await argumentBinding.BindModelAsync(parameter, testContext); // Assert Assert.True(modelState.IsValid); Assert.True(result.IsModelSet); var products = Assert.IsAssignableFrom <IEnumerable <ProductViewModel> >(result.Model); Assert.Equal(2, products.Count()); }
public async Task ComplexModel_EmptyPrefixSelected_NoMatchingValueProviderValue_WithFilteredValueProviders_NoValues() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Person5), BindingInfo = new BindingInfo() { BindingSource = BindingSource.Query, }, }; var testContext = ModelBindingTestHelper.GetTestContext(request => { // This value won't be used to select a prefix, because we're only looking at the query string. request.Form = new FormCollection(new Dictionary <string, StringValues>() { { "parameter", string.Empty }, }); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType <Person5>(modelBindingResult.Model); Assert.Null(model.Name); Assert.Empty(modelState); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); }
public async Task BindProperty_WithData_WithPrefix_GetsBound() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", }, ParameterType = typeof(Person) }; var testContext = ModelBindingTestHelper.GetTestContext(); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType <Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.False(boundPerson.Token.IsCancellationRequested); testContext.HttpContext.Abort(); Assert.True(boundPerson.Token.IsCancellationRequested); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState.Keys); }
public async Task BinderTypeOnParameterType_WithData_EmptyPrefix_GetsBound(BindingInfo bindingInfo) { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameters = typeof(TestController).GetMethod(nameof(TestController.Action)).GetParameters(); var parameter = new ControllerParameterDescriptor { Name = "Parameter1", BindingInfo = bindingInfo, ParameterInfo = parameters[0], ParameterType = typeof(Address), }; var testContext = ModelBindingTestHelper.GetTestContext(); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var address = Assert.IsType <Address>(modelBindingResult.Model); Assert.Equal("SomeStreet", address.Street); // ModelState Assert.True(modelState.IsValid); var kvp = Assert.Single(modelState); Assert.Equal("Street", kvp.Key); var entry = kvp.Value; Assert.NotNull(entry); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.NotNull(entry.RawValue); // Value is set by test model binder, no need to validate it. }
public async Task BindProperty_WithData_WithPrefix_GetsBound() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter" }, ParameterType = typeof(Person) }; var testContext = ModelBindingTestHelper.GetTestContext(); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType <Person>(modelBindingResult.Model); Assert.NotNull(boundPerson.Address); Assert.Equal("SomeStreet", boundPerson.Address.Street); // ModelState Assert.True(modelState.IsValid); var key = Assert.Single(modelState.Keys); Assert.Equal("CustomParameter.Address.Street", key); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); Assert.NotNull(modelState[key].RawValue); // Value is set by test model binder, no need to validate it. }
public async Task BindDateTimeParameter_WithDataFromBody_GetsBound() { // Arrange var input = "\"2020-02-01\""; var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "Parameter1", ParameterType = typeof(DateTime), BindingInfo = new BindingInfo { BindingSource = BindingSource.Body, } }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(input)); request.ContentType = "application/json"; }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var model = Assert.IsType <DateTime>(modelBindingResult.Model); Assert.Equal(new DateTime(2020, 02, 01, 0, 0, 0, DateTimeKind.Utc), model); // ModelState Assert.True(modelState.IsValid); }
public async Task FromBodyOnParameterType_WithData_Succeeds(BindingInfo bindingInfo) { // Arrange var inputText = "{ \"Street\" : \"someStreet\" }"; var metadataProvider = new TestModelMetadataProvider(); metadataProvider .ForType <Address6>() .BindingDetails(binding => binding.BindingSource = BindingSource.Body); var testContext = ModelBindingTestHelper.GetTestContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(inputText)); request.ContentType = "application/json"; }, metadataProvider: metadataProvider); var modelState = testContext.ModelState; var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices); var parameter = new ParameterDescriptor { Name = "parameter-name", BindingInfo = bindingInfo, ParameterType = typeof(Address6), }; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var address = Assert.IsType <Address6>(modelBindingResult.Model); Assert.Equal("someStreet", address.Street, StringComparer.Ordinal); Assert.True(modelState.IsValid); Assert.Empty(modelState); }
public async Task ActionParameter_BindingToAbstractionType_ThrowsException() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { ParameterType = typeof(AbstractClassWithNoDefaultConstructor), Name = "p" }; var testContext = ModelBindingTestHelper.GetTestContext(); // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => parameterBinder.BindModelAsync(parameter, testContext)); Assert.Equal( string.Format( CultureInfo.CurrentCulture, "Could not create an instance of type '{0}'. Model bound complex types must not be abstract or " + "value types and must have a parameterless constructor. Record types must have a single primary constructor.", typeof(AbstractClassWithNoDefaultConstructor).FullName), exception.Message); }
public async Task BindsJQueryFormatData_FromRequestBody() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Customer) }; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes( "Name=James&Address[0][City]=Redmond&Address[0][State][ShortName]=WA&Address[0][State][LongName]=Washington")); request.ContentType = "application/x-www-form-urlencoded;charset=utf-8"; }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType <Customer>(modelBindingResult.Model); Assert.Equal("James", model.Name); Assert.NotNull(model.Address); var address = Assert.Single(model.Address); Assert.Equal("Redmond", address.City); Assert.NotNull(address.State); Assert.Equal("WA", address.State.ShortName); Assert.Equal("Washington", address.State.LongName); Assert.True(modelState.IsValid); }
public async Task ComplexModel_PrefixSelected_ByValueProvider() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Person1), }; var testContext = ModelBindingTestHelper.GetTestContext(request => { // This will cause selection of the "parameter" prefix. request.QueryString = new QueryString("?parameter="); // This value won't be used, because we select the "parameter" prefix. request.Form = new FormCollection(new Dictionary <string, StringValues>() { { "Name", "Billy" }, }); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType <Person1>(modelBindingResult.Model); Assert.Null(model.Name); Assert.Empty(modelState); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); }
public async Task ActionParameter_NonSettableArrayModel_WithPrefix_DoesNotGetBound() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Address", BindingInfo = new BindingInfo() { BinderModelName = "prefix" }, ParameterType = typeof(Person5) }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.QueryString = QueryString.Create("prefix.Address[0].Street", "SomeStreet"); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); // Model Assert.NotNull(modelBindingResult.Model); var boundModel = Assert.IsType <Person5>(modelBindingResult.Model); // Arrays should not be updated. Assert.Empty(boundModel.Address); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState.Keys); }
public async Task BindProperty_FormFileCollectionInCollection_OutOfOrderFile() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "house", BindingInfo = new BindingInfo(), ParameterType = typeof(House) }; var data = "Some Data Is Better Than No Data."; var testContext = ModelBindingTestHelper.GetTestContext( request => { UpdateRequest(request, data + 1, "house.Garage.Cars[800].Specs"); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var house = Assert.IsType <House>(modelBindingResult.Model); Assert.NotNull(house.Garage); Assert.Empty(house.Garage.Cars); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState); }
public async Task BindModelAsync_WithBindProperty_DoesNotBindModel_WhenRequestIsGet() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Person), BindingInfo = BindingInfo.GetBindingInfo(new[] { new BindPropertyAttribute() }), }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.Method = "GET"; request.QueryString = new QueryString("?parameter.Name=Joey"); }); // Act var result = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.False(result.IsModelSet); }
public async Task BindParameter_WithEmptyData_BindsReferenceAndNullableObjects(Type parameterType) { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = parameterType }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.QueryString = QueryString.Create("Parameter1", string.Empty); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model Assert.Null(modelBindingResult.Model); // ModelState Assert.True(modelState.IsValid); var key = Assert.Single(modelState.Keys); Assert.Equal("Parameter1", key); Assert.Equal(string.Empty, modelState[key].AttemptedValue); Assert.Equal(string.Empty, modelState[key].RawValue); Assert.Empty(modelState[key].Errors); }
public async Task FromBodyAllowingEmptyInputOnActionParameter_EmptyBody_BindsToNullValue() { // Arrange var parameter = new ParameterDescriptor { Name = "Parameter1", BindingInfo = new BindingInfo { BinderModelName = "CustomParameter", BindingSource = BindingSource.Body }, ParameterType = typeof(Person) }; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(string.Empty)); request.ContentType = "application/json"; request.ContentLength = 0; }); testContext.MvcOptions.AllowEmptyInputInBodyModelBinding = true; var modelState = testContext.ModelState; var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices); // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); Assert.Null(modelBindingResult.Model); Assert.True(modelState.IsValid); Assert.Empty(modelState); }
public async Task KeyValuePairModelBinder_SimpleTypes_WithNoValue_AddsError() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "parameter", ParameterType = typeof(KeyValuePair <string, int>) }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.QueryString = new QueryString("?parameter.Key=10"); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.False(modelBindingResult.IsModelSet); Assert.Equal(2, modelState.Count); Assert.False(modelState.IsValid); Assert.Equal(1, modelState.ErrorCount); var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter.Key").Value; Assert.Empty(entry.Errors); Assert.Equal("10", entry.AttemptedValue); Assert.Equal("10", entry.RawValue); entry = Assert.Single(modelState, kvp => kvp.Key == "parameter.Value").Value; var error = Assert.Single(entry.Errors); Assert.Null(error.Exception); Assert.Equal("A value is required.", error.ErrorMessage); }
public async Task BindParameterFromService_WithData_GetsBound() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", BindingSource = BindingSource.Services }, // Using a service type already in defaults. ParameterType = typeof(ITypeActivatorCache) }; var testContext = ModelBindingTestHelper.GetTestContext(); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var provider = Assert.IsAssignableFrom <ITypeActivatorCache>(modelBindingResult.Model); Assert.NotNull(provider); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState.Keys); }
public async Task FromBodyAndRequiredOnInnerValueTypeProperty_NotBound_JsonFormatterSuccessful() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "Parameter1", BindingInfo = new BindingInfo { BinderModelName = "CustomParameter", }, ParameterType = typeof(Person5) }; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes("{ \"Number\": 5 }")); request.ContentType = "application/json"; }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var boundPerson = Assert.IsType <Person5>(modelBindingResult.Model); Assert.NotNull(boundPerson.Address); Assert.Equal(5, boundPerson.Address.Number); Assert.Equal(0, boundPerson.Address.RequiredNumber); Assert.True(modelState.IsValid); Assert.Empty(modelState); }
public async Task TryUpdateModel_SettableArrayModel_WithPrefix_CreatesArray() { // Arrange var testContext = ModelBindingTestHelper.GetTestContext(request => { request.QueryString = QueryString.Create("prefix.Address[0].Street", "SomeStreet"); }); var modelState = testContext.ModelState; var model = new Person4(); // Act var result = await TryUpdateModelAsync(model, "prefix", testContext); // Assert Assert.True(result); // Model Assert.NotNull(model.Address); Assert.Single(model.Address); Assert.Equal("SomeStreet", model.Address[0].Street); Assert.Null(model.Address[0].City); // ModelState Assert.True(modelState.IsValid); var entry = Assert.Single(modelState); Assert.Equal("prefix.Address[0].Street", entry.Key); var state = entry.Value; Assert.Equal("SomeStreet", state.AttemptedValue); Assert.Equal("SomeStreet", state.RawValue); Assert.Empty(state.Errors); Assert.Equal(ModelValidationState.Valid, state.ValidationState); }
public async Task ActionParameter_UsingComplexTypeModelBinder_ModelPropertyTypeWithNoParameterlessConstructor_ThrowsException() { // Arrange var parameterType = typeof(Class1); var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "p", ParameterType = parameterType }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.QueryString = QueryString.Create("Name", "James").Add("Property1.City", "Seattle"); }, updateOptions: options => { options.ModelBinderProviders.RemoveType <ComplexObjectModelBinderProvider>(); #pragma warning disable CS0618 // Type or member is obsolete options.ModelBinderProviders.Add(new ComplexTypeModelBinderProvider()); #pragma warning restore CS0618 // Type or member is obsolete }); var modelState = testContext.ModelState; // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => parameterBinder.BindModelAsync(parameter, testContext)); Assert.Equal( string.Format( CultureInfo.CurrentCulture, "Could not create an instance of type '{0}'. Model bound complex types must not be abstract or " + "value types and must have a parameterless constructor. Alternatively, set the '{1}' property to" + " a non-null value in the '{2}' constructor.", typeof(ClassWithNoDefaultConstructor).FullName, nameof(Class1.Property1), typeof(Class1).FullName), exception.Message); }
public async Task BindParameterFromService_NoService_Throws() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "ControllerProperty", BindingInfo = new BindingInfo { BindingSource = BindingSource.Services, }, // Use a service type not available in DI. ParameterType = typeof(IActionResult), }; var testContext = ModelBindingTestHelper.GetTestContext(); // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>( () => parameterBinder.BindModelAsync(parameter, testContext)); Assert.Contains(typeof(IActionResult).FullName, exception.Message); }
public async Task ModelMetadataTypeAttribute_ValidDerivedClass_NoModelStateErrors() { // Arrange var input = "{ \"Name\": \"MVC\", \"Contact\":\"4258959019\", \"Category\":\"Technology\"," + "\"CompanyName\":\"Microsoft\", \"Country\":\"USA\", \"Version\":\"2\"," + "\"DatePurchased\": \"/Date(1297246301973)/\", \"Price\" : \"110\" }"; var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BindingSource = BindingSource.Body }, ParameterType = typeof(SoftwareViewModel) }; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(input)); request.ContentType = "application/json"; }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var boundPerson = Assert.IsType <SoftwareViewModel>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.True(modelState.IsValid); }
public async Task ModelMetadataTypeAttribute_ValidBaseClass_NoModelStateErrors() { // Arrange var input = "{ \"Name\": \"MVC\", \"Contact\":\"4258959019\", \"Category\":\"Technology\"," + "\"CompanyName\":\"Microsoft\", \"Country\":\"USA\",\"Price\": 21, " + "\"ProductDetails\": {\"Detail1\": \"d1\", \"Detail2\": \"d2\", \"Detail3\": \"d3\"}}"; var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", ParameterType = typeof(ProductViewModel), BindingInfo = new BindingInfo() { BindingSource = BindingSource.Body } }; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(input)); request.ContentType = "application/json;charset=utf-8"; }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert Assert.True(modelBindingResult.IsModelSet); var boundPerson = Assert.IsType <ProductViewModel>(modelBindingResult.Model); Assert.True(modelState.IsValid); Assert.NotNull(boundPerson); }
public async Task BindParameter_NoData_BindsWithEmptyCollection() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "Parameter1", BindingInfo = new BindingInfo { BinderModelName = "CustomParameter", }, ParameterType = typeof(IFormCollection) }; // No data is passed. var testContext = ModelBindingTestHelper.GetTestContext(); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult var collection = Assert.IsAssignableFrom <IFormCollection>(modelBindingResult.Model); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState); // FormCollection Assert.Empty(collection); Assert.Empty(collection.Files); Assert.Empty(collection.Keys); }
private ModelBindingTestContext GetModelBindingTestContext( Action <HttpRequest> updateRequest = null, Action <MvcOptions> updateOptions = null) { return(ModelBindingTestHelper.GetTestContext(updateRequest, updateOptions)); }
public async Task BindModelAsync_WithBindPageProperty_EnforcesBindRequired(int?input, bool isValid) { // Arrange var propertyInfo = typeof(TestPage).GetProperty(nameof(TestPage.BindRequiredProperty)); var propertyDescriptor = new PageBoundPropertyDescriptor { BindingInfo = BindingInfo.GetBindingInfo(new[] { new FromQueryAttribute { Name = propertyInfo.Name }, }), Name = propertyInfo.Name, ParameterType = propertyInfo.PropertyType, Property = propertyInfo, }; var typeInfo = typeof(TestPage).GetTypeInfo(); var actionDescriptor = new CompiledPageActionDescriptor { BoundProperties = new[] { propertyDescriptor }, HandlerTypeInfo = typeInfo, ModelTypeInfo = typeInfo, PageTypeInfo = typeInfo, }; var testContext = ModelBindingTestHelper.GetTestContext(request => { request.Method = "POST"; if (input.HasValue) { request.QueryString = new QueryString($"?{propertyDescriptor.Name}={input.Value}"); } }); var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var parameterBinder = ModelBindingTestHelper.GetParameterBinder(modelMetadataProvider); var modelBinderFactory = ModelBindingTestHelper.GetModelBinderFactory(modelMetadataProvider); var modelMetadata = modelMetadataProvider .GetMetadataForProperty(typeof(TestPage), propertyDescriptor.Name); var pageBinder = PageBinderFactory.CreatePropertyBinder( parameterBinder, modelMetadataProvider, modelBinderFactory, actionDescriptor); var pageContext = new PageContext { ActionDescriptor = actionDescriptor, HttpContext = testContext.HttpContext, RouteData = testContext.RouteData, ValueProviderFactories = testContext.ValueProviderFactories, }; var page = new TestPage(); // Act await pageBinder(pageContext, page); // Assert Assert.Equal(isValid, pageContext.ModelState.IsValid); if (isValid) { Assert.Equal(input.Value, page.BindRequiredProperty); } }
public async Task BindPropertyFromHeader_WithPrefix_GetsBound_ForSimpleTypes() { // Arrange var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "prefix", }, ParameterType = typeof(Product) }; var testContext = GetModelBindingTestContext( request => { request.Headers.Add("NoCommaString", "someValue"); request.Headers.Add("OneCommaSeparatedString", "one, two, three"); request.Headers.Add("IntProperty", "10"); request.Headers.Add("NullableIntProperty", "300"); request.Headers.Add("ArrayOfString", "first, second"); request.Headers.Add("EnumerableOfDouble", "10.51, 45.44"); request.Headers.Add("ListOfEnum", "Sedan, Coupe"); request.Headers.Add("ListOfOrderWithTypeConverter", "10"); }); var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var product = Assert.IsType <Product>(modelBindingResult.Model); Assert.NotNull(product); Assert.NotNull(product.Manufacturer); Assert.Equal("someValue", product.Manufacturer.NoCommaString); Assert.Equal("one, two, three", product.Manufacturer.OneCommaSeparatedStringProperty); Assert.Equal(10, product.Manufacturer.IntProperty); Assert.Equal(300, product.Manufacturer.NullableIntProperty); Assert.Null(product.Manufacturer.NullableLongProperty); Assert.Equal(new[] { "first", "second" }, product.Manufacturer.ArrayOfString); Assert.Equal(new double[] { 10.51, 45.44 }, product.Manufacturer.EnumerableOfDoubleProperty); Assert.Equal(new CarType[] { CarType.Sedan, CarType.Coupe }, product.Manufacturer.ListOfEnum); var orderWithTypeConverter = Assert.Single(product.Manufacturer.ListOfOrderWithTypeConverterProperty); Assert.Equal(10, orderWithTypeConverter.Id); // ModelState Assert.True(modelState.IsValid); Assert.Collection( modelState.OrderBy(kvp => kvp.Key), kvp => { Assert.Equal("prefix.Manufacturer.ArrayOfString", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("first,second", entry.AttemptedValue); Assert.Equal(new[] { "first", "second" }, entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.EnumerableOfDouble", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("10.51,45.44", entry.AttemptedValue); Assert.Equal(new[] { "10.51", "45.44" }, entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.IntProperty", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("10", entry.AttemptedValue); Assert.Equal("10", entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.ListOfEnum", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("Sedan,Coupe", entry.AttemptedValue); Assert.Equal(new[] { "Sedan", "Coupe" }, entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.ListOfOrderWithTypeConverter", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("10", entry.AttemptedValue); Assert.Equal("10", entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.NoCommaString", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("someValue", entry.AttemptedValue); Assert.Equal("someValue", entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.NullableIntProperty", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("300", entry.AttemptedValue); Assert.Equal("300", entry.RawValue); }, kvp => { Assert.Equal("prefix.Manufacturer.OneCommaSeparatedString", kvp.Key); var entry = kvp.Value; Assert.Empty(entry.Errors); Assert.Equal(ModelValidationState.Valid, entry.ValidationState); Assert.Equal("one, two, three", entry.AttemptedValue); Assert.Equal("one, two, three", entry.RawValue); }); }
public async Task BindProperty_FormFileCollectionInCollection_WithPrefix() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor { Name = "house", BindingInfo = new BindingInfo(), ParameterType = typeof(House) }; var data = "Some Data Is Better Than No Data."; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.QueryString = QueryString.Create("house.Garage.Cars[0].Name", "Accord"); UpdateRequest(request, data + 1, "house.Garage.Cars[0].Specs"); AddFormFile(request, data + 2, "house.Garage.Cars[1].Specs"); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var house = Assert.IsType <House>(modelBindingResult.Model); Assert.NotNull(house.Garage); Assert.NotNull(house.Garage.Cars); Assert.Collection( house.Garage.Cars, car => { Assert.Equal("Accord", car.Name); var file = Assert.Single(car.Specs); using var reader = new StreamReader(file.OpenReadStream()); Assert.Equal(data + 1, reader.ReadToEnd()); }, car => { Assert.Null(car.Name); var file = Assert.Single(car.Specs); using var reader = new StreamReader(file.OpenReadStream()); Assert.Equal(data + 2, reader.ReadToEnd()); }); // ModelState Assert.True(modelState.IsValid); Assert.Equal(3, modelState.Count); var entry = Assert.Single(modelState, e => e.Key == "house.Garage.Cars[0].Name").Value; Assert.Equal("Accord", entry.AttemptedValue); Assert.Equal("Accord", entry.RawValue); Assert.Single(modelState, e => e.Key == "house.Garage.Cars[0].Specs"); Assert.Single(modelState, e => e.Key == "house.Garage.Cars[1].Specs"); }
public async Task BindProperty_OnFormFileInNestedSubClass_AtSecondLevel_WhenSiblingPropertiesAreNotSpecified() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(Group) }; var data = "Some Data Is Better Than No Data."; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.QueryString = QueryString.Create("GroupName", "TestGroup"); UpdateRequest(request, data, "Person.Address.File"); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var group = Assert.IsType <Group>(modelBindingResult.Model); Assert.Equal("TestGroup", group.GroupName); var boundPerson = group.Person; Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Address); var file = Assert.IsAssignableFrom <IFormFile>(boundPerson.Address.File); Assert.Equal("form-data; name=Person.Address.File; filename=text.txt", file.ContentDisposition); using var reader = new StreamReader(boundPerson.Address.File.OpenReadStream()); Assert.Equal(data, reader.ReadToEnd()); Assert.Equal(0, boundPerson.Address.Zip); // ModelState Assert.True(modelState.IsValid); Assert.Collection( modelState.OrderBy(kvp => kvp.Key), kvp => { var(key, value) = kvp; Assert.Equal("GroupName", kvp.Key); Assert.Equal("TestGroup", value.RawValue); Assert.Empty(value.Errors); Assert.Equal(ModelValidationState.Valid, value.ValidationState); }, kvp => { var(key, value) = kvp; Assert.Equal("Person.Address.File", kvp.Key); Assert.Null(value.RawValue); Assert.Empty(value.Errors); Assert.Equal(ModelValidationState.Valid, value.ValidationState); }); }
public async Task BindProperty_OnFormFileInNestedSubClass_AtThirdLevel_RecursiveModel() { // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() { Name = "fleet", BindingInfo = new BindingInfo(), ParameterType = typeof(Fleet) }; var data = "Some Data Is Better Than No Data."; var testContext = ModelBindingTestHelper.GetTestContext( request => { request.QueryString = QueryString.Create("fleet.Garage.Name", "WestEnd"); UpdateRequest(request, data, "fleet.Garage.Vehicles[0].BackupVehicle.Spec"); }); var modelState = testContext.ModelState; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.True(modelBindingResult.IsModelSet); // Model var fleet = Assert.IsType <Fleet>(modelBindingResult.Model); Assert.Null(fleet.Id); Assert.NotNull(fleet.Garage); Assert.NotNull(fleet.Garage.Vehicles); var vehicle = Assert.Single(fleet.Garage.Vehicles); Assert.Null(vehicle.Spec); Assert.NotNull(vehicle.BackupVehicle); var file = Assert.IsAssignableFrom <IFormFile>(vehicle.BackupVehicle.Spec); using var reader = new StreamReader(file.OpenReadStream()); Assert.Equal(data, reader.ReadToEnd()); Assert.Null(vehicle.Name); // ModelState Assert.True(modelState.IsValid); Assert.Collection( modelState.OrderBy(kvp => kvp.Key), kvp => { var(key, value) = kvp; Assert.Equal("fleet.Garage.Name", kvp.Key); Assert.Equal("WestEnd", value.RawValue); Assert.Empty(value.Errors); Assert.Equal(ModelValidationState.Valid, value.ValidationState); }, kvp => { var(key, value) = kvp; Assert.Equal("fleet.Garage.Vehicles[0].BackupVehicle.Spec", kvp.Key); Assert.Equal(ModelValidationState.Valid, value.ValidationState); }); }