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());
    }
Example #2
0
    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);
    }
Example #4
0
    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.
    }
Example #5
0
    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);
    }
Example #9
0
    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);
    }
Example #10
0
    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);
    }
Example #12
0
    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);
    }
Example #16
0
    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);
    }
Example #18
0
    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);
    }
Example #19
0
    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);
    }
Example #22
0
    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);
    }
Example #23
0
    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);
        });
    }
Example #28
0
    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");
    }
Example #29
0
    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);
        });
    }
Example #30
0
    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);
        });
    }