// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.TestHost; using ModelBindingWebSite; using Newtonsoft.Json; using Xunit; namespace Microsoft.AspNet.Mvc.FunctionalTests { public class ModelBindingTests { private readonly IServiceProvider _services = TestHelper.CreateServices("ModelBindingWebSite"); private readonly Action _app = new ModelBindingWebSite.Startup().Configure; [Theory] [InlineData("RestrictValueProvidersUsingFromRoute", "valueFromRoute")] [InlineData("RestrictValueProvidersUsingFromQuery", "valueFromQuery")] [InlineData("RestrictValueProvidersUsingFromForm", "valueFromForm")] public async Task CompositeModelBinder_Restricts_ValueProviders(string actionName, string expectedValue) { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Provide all three values, it should bind based on the attribute on the action method. var request = new HttpRequestMessage(HttpMethod.Post, string.Format("http://localhost/CompositeTest/{0}/valueFromRoute?param=valueFromQuery", actionName)); var nameValueCollection = new List> { new KeyValuePair("param", "valueFromForm"), }; request.Content = new FormUrlEncodedContent(nameValueCollection); // Act var response = await client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(expectedValue, await response.Content.ReadAsStringAsync()); } [Fact] public async Task TryUpdateModel_WithAPropertyFromBody() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // the name would be of customer.Department.Name // and not for the top level customer object. var input = "{\"Name\":\"RandomDepartment\"}"; var content = new StringContent(input, Encoding.UTF8, "application/json"); // Act var response = await client.PostAsync("http://localhost/Home/GetCustomer?Id=1234", content); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var customer = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(customer.Department); Assert.Equal("RandomDepartment", customer.Department.Name); Assert.Equal(1234, customer.Id); Assert.Equal(25, customer.Age); Assert.Equal("dummy", customer.Name); } [Fact] public async Task CanModelBindServiceToAnArgument() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/FromServices_Calculator/Add?left=1234&right=1"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("1235", await response.Content.ReadAsStringAsync()); } [Fact] public async Task CanModelBindServiceToAProperty() { var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync( "http://localhost/FromServices_Calculator/Calculate?Left=10&Right=5&Operator=*"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("50", await response.Content.ReadAsStringAsync()); } [Fact] public async Task CanModelBindServiceToAProperty_OnBaseType() { var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync( "http://localhost/FromServices_Calculator/CalculateWithPrecision?Left=10&Right=5&Operator=*"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("50", await response.Content.ReadAsStringAsync()); } [Fact] public async Task MultipleParametersMarkedWithFromBody_Throws() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act & Assert var ex = await Assert.ThrowsAsync(() => client.GetAsync("http://localhost/FromAttributes/FromBodyParametersThrows")); Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.", ex.Message); } [Fact] public async Task MultipleParameterAndPropertiesMarkedWithFromBody_Throws() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act & Assert var ex = await Assert.ThrowsAsync(() => client.GetAsync("http://localhost/FromAttributes/FromBodyParameterAndPropertyThrows")); Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.", ex.Message); } [Fact] public async Task MultipleParametersMarkedWith_FromFormAndFromBody_Throws() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act & Assert var ex = await Assert.ThrowsAsync(() => client.GetAsync("http://localhost/FromAttributes/FormAndBody_AsParameters_Throws")); Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.", ex.Message); } [Fact] public async Task MultipleParameterAndPropertiesMarkedWith_FromFormAndFromBody_Throws() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act & Assert var ex = await Assert.ThrowsAsync(() => client.GetAsync("http://localhost/FromAttributes/FormAndBody_Throws")); Assert.Equal("More than one parameter and/or property is bound to the HTTP request's content.", ex.Message); } [Fact] public async Task CanBind_MultipleParameters_UsingFromForm() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/FromAttributes/MultipleFromFormParameters"); var nameValueCollection = new List> { new KeyValuePair("homeAddress.Street", "1"), new KeyValuePair("homeAddress.State", "WA_Form_Home"), new KeyValuePair("homeAddress.Zip", "2"), new KeyValuePair("officeAddress.Street", "3"), new KeyValuePair("officeAddress.State", "WA_Form_Office"), new KeyValuePair("officeAddress.Zip", "4"), }; request.Content = new FormUrlEncodedContent(nameValueCollection); // Act var response = await client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var user = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.Equal("WA_Form_Home", user.HomeAddress.State); Assert.Equal(1, user.HomeAddress.Street); Assert.Equal(2, user.HomeAddress.Zip); Assert.Equal("WA_Form_Office", user.OfficeAddress.State); Assert.Equal(3, user.OfficeAddress.Street); Assert.Equal(4, user.OfficeAddress.Zip); } [Fact] public async Task CanBind_MultipleProperties_UsingFromForm() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/FromAttributes/MultipleFromFormParameterAndProperty"); var nameValueCollection = new List> { new KeyValuePair("Street", "1"), new KeyValuePair("State", "WA_Form_Home"), new KeyValuePair("Zip", "2"), new KeyValuePair("officeAddress.Street", "3"), new KeyValuePair("officeAddress.State", "WA_Form_Office"), new KeyValuePair("officeAddress.Zip", "4"), }; request.Content = new FormUrlEncodedContent(nameValueCollection); // Act var response = await client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var user = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.Equal("WA_Form_Home", user.HomeAddress.State); Assert.Equal(1, user.HomeAddress.Street); Assert.Equal(2, user.HomeAddress.Zip); Assert.Equal("WA_Form_Office", user.OfficeAddress.State); Assert.Equal(3, user.OfficeAddress.Street); Assert.Equal(4, user.OfficeAddress.Zip); } [Fact] public async Task CanBind_ComplexData_OnParameters_UsingFromAttributes() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Provide all three values, it should bind based on the attribute on the action method. var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/FromAttributes/GetUser/5/WA_Route/6" + "?Street=3&State=WA_Query&Zip=4"); var nameValueCollection = new List> { new KeyValuePair("Street", "1"), new KeyValuePair("State", "WA_Form"), new KeyValuePair("Zip", "2"), }; request.Content = new FormUrlEncodedContent(nameValueCollection); // Act var response = await client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var user = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); // Assert FromRoute Assert.Equal("WA_Route", user.HomeAddress.State); Assert.Equal(5, user.HomeAddress.Street); Assert.Equal(6, user.HomeAddress.Zip); // Assert FromForm Assert.Equal("WA_Form", user.OfficeAddress.State); Assert.Equal(1, user.OfficeAddress.Street); Assert.Equal(2, user.OfficeAddress.Zip); // Assert FromQuery Assert.Equal("WA_Query", user.ShippingAddress.State); Assert.Equal(3, user.ShippingAddress.Street); Assert.Equal(4, user.ShippingAddress.Zip); } [Fact] public async Task CanBind_ComplexData_OnProperties_UsingFromAttributes() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Provide all three values, it should bind based on the attribute on the action method. var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/FromAttributes/GetUser_FromForm/5/WA_Route/6" + "?ShippingAddress.Street=3&ShippingAddress.State=WA_Query&ShippingAddress.Zip=4"); var nameValueCollection = new List> { new KeyValuePair("OfficeAddress.Street", "1"), new KeyValuePair("OfficeAddress.State", "WA_Form"), new KeyValuePair("OfficeAddress.Zip", "2"), }; request.Content = new FormUrlEncodedContent(nameValueCollection); // Act var response = await client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var user = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); // Assert FromRoute Assert.Equal("WA_Route", user.HomeAddress.State); Assert.Equal(5, user.HomeAddress.Street); Assert.Equal(6, user.HomeAddress.Zip); // Assert FromForm Assert.Equal("WA_Form", user.OfficeAddress.State); Assert.Equal(1, user.OfficeAddress.Street); Assert.Equal(2, user.OfficeAddress.Zip); // Assert FromQuery Assert.Equal("WA_Query", user.ShippingAddress.State); Assert.Equal(3, user.ShippingAddress.Street); Assert.Equal(4, user.ShippingAddress.Zip); } [Fact] public async Task CanBind_ComplexData_OnProperties_UsingFromAttributes_WithBody() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Provide all three values, it should bind based on the attribute on the action method. var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/FromAttributes/GetUser_FromBody/5/WA_Route/6" + "?ShippingAddress.Street=3&ShippingAddress.State=WA_Query&ShippingAddress.Zip=4"); var input = "{\"State\":\"WA_Body\",\"Street\":1,\"Zip\":2}"; request.Content = new StringContent(input, Encoding.UTF8, "application/json"); // Act var response = await client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var user = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); // Assert FromRoute Assert.Equal("WA_Route", user.HomeAddress.State); Assert.Equal(5, user.HomeAddress.Street); Assert.Equal(6, user.HomeAddress.Zip); // Assert FromBody Assert.Equal("WA_Body", user.OfficeAddress.State); Assert.Equal(1, user.OfficeAddress.Street); Assert.Equal(2, user.OfficeAddress.Zip); // Assert FromQuery Assert.Equal("WA_Query", user.ShippingAddress.State); Assert.Equal(3, user.ShippingAddress.Street); Assert.Equal(4, user.ShippingAddress.Zip); } [Fact] public async Task NonExistingModelBinder_ForABinderMetadata_DoesNotRecurseInfinitely() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act & Assert var response = await client.GetStringAsync("http://localhost/WithBinderMetadata/EchoDocument"); var document = JsonConvert.DeserializeObject (response); Assert.NotNull(document); Assert.Null(document.Version); Assert.Null(document.SubDocument); } [Fact] public async Task ParametersWithNoValueProviderMetadataUseTheAvailableValueProviders() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/WithBinderMetadata" + "/ParametersWithNoValueProviderMetadataUseTheAvailableValueProviders" + "?Name=somename&Age=12"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var emp = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.Null(emp.Department); Assert.Equal("somename", emp.Name); Assert.Equal(12, emp.Age); } [Fact] public async Task ParametersAreAlwaysCreated_IfValuesAreProvidedWithoutModelName() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/WithoutBinderMetadata" + "/GetPersonParameter" + "?Name=somename&Age=12"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var person = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(person); Assert.Equal("somename", person.Name); Assert.Equal(12, person.Age); } [Fact] public async Task ParametersAreAlwaysCreated_IfValueIsProvidedForModelName() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/WithoutBinderMetadata" + "/GetPersonParameter?p="); // here p is the model name. //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var person = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(person); Assert.Null(person.Name); Assert.Equal(0, person.Age); } [Fact] public async Task ParametersAreAlwaysCreated_IfNoValuesAreProvided() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/WithoutBinderMetadata" + "/GetPersonParameter"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var person = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(person); Assert.Null(person.Name); Assert.Equal(0, person.Age); } [Fact] public async Task PropertiesAreBound_IfTheyAreProvidedByValueProviders() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Properties" + "/GetCompany?Employees[0].Name=somename&Age=12"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var company = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(company); Assert.NotNull(company.Employees); Assert.Equal(1, company.Employees.Count); Assert.NotNull(company.Employees[0].Name); } [Fact] public async Task PropertiesAreBound_IfTheyAreMarkedExplicitly() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Properties" + "/GetCompany"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var company = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(company); Assert.NotNull(company.CEO); Assert.Null(company.CEO.Name); } [Fact] public async Task PropertiesAreBound_IfTheyArePocoMetadataMarkedTypes() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Properties" + "/GetCompany"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var company = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(company); // Department property is not null because it was a marker poco. Assert.NotNull(company.Department); // beacause no value is provided. Assert.Null(company.Department.Name); } [Fact] public async Task PropertiesAreNotBound_ByDefault() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Properties" + "/GetCompany"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var company = JsonConvert.DeserializeObject( await response.Content.ReadAsStringAsync()); Assert.NotNull(company); Assert.Null(company.Employees); } [Theory] [InlineData("http://localhost/Home/ActionWithPersonFromUrlWithPrefix/Javier/26")] [InlineData("http://localhost/Home/ActionWithPersonFromUrlWithoutPrefix/Javier/26")] public async Task CanBind_ComplexData_FromRouteData(string url) { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync(url); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var body = await response.Content.ReadAsStringAsync(); Assert.NotNull(body); var person = JsonConvert.DeserializeObject(body); Assert.NotNull(person); Assert.Equal("Javier", person.Name); Assert.Equal(26, person.Age); } [Fact] public async Task ModelBindCancellationTokenParameteres() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Home/ActionWithCancellationToken"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("true", await response.Content.ReadAsStringAsync()); } [Fact] public async Task ModelBindCancellationToken_ForProperties() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync( "http://localhost/Home/ActionWithCancellationTokenModel?wrapper=bogusValue"); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("true", await response.Content.ReadAsStringAsync()); } [Fact] public async Task ModelBindingBindsBase64StringsToByteArrays() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Home/Index?byteValues=SGVsbG9Xb3JsZA=="); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("HelloWorld", await response.Content.ReadAsStringAsync()); } [Fact] public async Task ModelBindingBindsEmptyStringsToByteArrays() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/Home/Index?byteValues="); //Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("\0", await response.Content.ReadAsStringAsync()); } [Fact] public async Task ModelBinding_LimitsErrorsToMaxErrorCount() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); var queryString = string.Join("=&", Enumerable.Range(0, 10).Select(i => "field" + i)); // Act var response = await client.GetStringAsync("http://localhost/Home/ModelWithTooManyValidationErrors?" + queryString); //Assert var json = JsonConvert.DeserializeObject>(response); // 8 is the value of MaxModelValidationErrors for the application being tested. Assert.Equal(8, json.Count); Assert.Equal("The Field1 field is required.", json["Field1.Field1"]); Assert.Equal("The Field2 field is required.", json["Field1.Field2"]); Assert.Equal("The Field3 field is required.", json["Field1.Field3"]); Assert.Equal("The Field1 field is required.", json["Field2.Field1"]); Assert.Equal("The Field2 field is required.", json["Field2.Field2"]); Assert.Equal("The Field3 field is required.", json["Field2.Field3"]); Assert.Equal("The Field1 field is required.", json["Field3.Field1"]); Assert.Equal("The maximum number of allowed model errors has been reached.", json[""]); } [Fact] public async Task ModelBinding_ValidatesAllPropertiesInModel() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/Home/ModelWithFewValidationErrors?model="); //Assert var json = JsonConvert.DeserializeObject>(response); Assert.Equal(3, json.Count); Assert.Equal("The Field1 field is required.", json["model.Field1"]); Assert.Equal("The Field2 field is required.", json["model.Field2"]); Assert.Equal("The Field3 field is required.", json["model.Field3"]); } [Fact] public async Task BindAttribute_AppliesAtBothParameterAndTypeLevelTogether_BlacklistedAtEitherLevelIsNotBound() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/BindAttribute/" + "BindAtParamterLevelAndBindAtTypeLevelAreBothEvaluated_BlackListingAtEitherLevelDoesNotBind" + "?param1.IncludedExplicitlyAtTypeLevel=someValue¶m2.ExcludedExplicitlyAtTypeLevel=someValue"); // Assert var json = JsonConvert.DeserializeObject>(response); Assert.Equal(2, json.Count); Assert.Null(json["param1.IncludedExplicitlyAtTypeLevel"]); Assert.Null(json["param2.ExcludedExplicitlyAtTypeLevel"]); } [Fact] public async Task BindAttribute_AppliesAtBothParameterAndTypeLevelTogether_WhitelistedAtBothLevelsIsBound() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/BindAttribute/" + "BindAtParamterLevelAndBindAtTypeLevelAreBothEvaluated_WhiteListingAtBothLevelBinds" + "?param1.IncludedExplicitlyAtTypeLevel=someValue¶m2.ExcludedExplicitlyAtTypeLevel=someValue"); // Assert var json = JsonConvert.DeserializeObject>(response); Assert.Equal(1, json.Count); Assert.Equal("someValue", json["param1.IncludedExplicitlyAtTypeLevel"]); } [Fact] public async Task BindAttribute_AppliesAtBothParameterAndTypeLevelTogether_WhitelistingAtOneLevelIsNotBound() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/BindAttribute/" + "BindAtParamterLevelAndBindAtTypeLevelAreBothEvaluated_WhiteListingAtOnlyOneLevelDoesNotBind" + "?param1.IncludedExplicitlyAtTypeLevel=someValue¶m1.IncludedExplicitlyAtParameterLevel=someValue"); // Assert var json = JsonConvert.DeserializeObject>(response); Assert.Equal(2, json.Count); Assert.Null(json["param1.IncludedExplicitlyAtParameterLevel"]); Assert.Null(json["param1.IncludedExplicitlyAtTypeLevel"]); } [Fact] public async Task BindAttribute_BindsUsingParameterPrefix() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/BindAttribute/" + "BindParameterUsingParameterPrefix" + "?randomPrefix.Value=someValue"); // Assert Assert.Equal("someValue", response); } [Fact] public async Task BindAttribute_DoesNotUseTypePrefix() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/BindAttribute/" + "TypePrefixIsNeverUsed" + "?param.Value=someValue"); // Assert Assert.Equal("someValue", response); } [Fact] public async Task BindAttribute_FallsBackOnEmptyPrefixIfNoParameterPrefixIsProvided() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetStringAsync("http://localhost/BindAttribute/" + "TypePrefixIsNeverUsed" + "?Value=someValue"); // Assert Assert.Equal("someValue", response); } [Fact] public async Task BindAttribute_DoesNotFallBackOnEmptyPrefixIfParameterPrefixIsProvided() { // Arrange var server = TestServer.Create(_services, _app); var client = server.CreateClient(); // Act var response = await client.GetAsync("http://localhost/BindAttribute/" + "BindParameterUsingParameterPrefix" + "?Value=someValue"); // Assert Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync()); } } }