public async Task BindPropertyFromService_WithData_WithEmptyPrefix_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(Person) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Address.OutputFormatter); // ModelState Assert.True(modelState.IsValid); // For non user bound models there should be no entry in model state. Assert.Empty(modelState); }
public async Task GenericModelBinder_BindsCollection_ElementTypeFromGreedyModelBinder_EmptyPrefix_Success() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(List<IFormCollection>) }; // Need to have a key here so that the GenericModelBinder will recurse to bind elements. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?index=10"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType<List<IFormCollection>>(modelBindingResult.Model); Assert.Equal(1, model.Count); Assert.NotNull(model[0]); Assert.Equal(0, modelState.Count); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); }
public async Task BindProperty_WithData_WithEmptyPrefix_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(Person) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Token); // ModelState Assert.True(modelState.IsValid); Assert.Equal(0, modelState.Count); }
public void Add(ParameterDescriptor parameterDescriptor, string value, IWatchable watchable) { lock (_itemsLock) { _items.Add(new Tuple<ParameterDescriptor, string, IWatchable>(parameterDescriptor, value, watchable)); } }
public async Task FromBodyOnActionParameter_EmptyBody_BindsToNullValue() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", BindingSource = BindingSource.Body }, ParameterType = typeof(Person) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(string.Empty)); request.ContentType = "application/json"; }); var httpContext = operationContext.HttpContext; var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); Assert.Null(modelBindingResult.Model); Assert.Empty(modelState.Keys); Assert.True(modelState.IsValid); }
public void Arguments_HaveCorrectDescription_Returns_CorrectValue( string propertyName, string expectedDescription) { //Arrange var command = new CommandLineApplication(); var property = typeof(TestClass).GetProperty(propertyName); var descriptor = new ParameterDescriptor(property); //Act descriptor.AddCommandLineParameterTo(command); //Assert var actualOption = command.Arguments.First(); Assert.Equal(propertyName, actualOption.Name); Assert.Equal(expectedDescription, actualOption.Description); //Arrange command.Execute(new string[0] { }); //Assert Assert.Equal(null, descriptor.Value); //Is this right assumption to test? //Arrange command.Execute(new string[] { "PassedValue" }); //Assert Assert.Equal("PassedValue", descriptor.Value); }
public async Task BindParameter_WithModelBinderType_NoData_ReturnsNull() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderType = typeof(NullModelNotSetModelBinder) }, ParameterType = typeof(string) }; // No data is passed. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.Null(modelBindingResult); // ModelState (not set unless inner binder sets it) Assert.True(modelState.IsValid); Assert.Empty(modelState); }
public async Task BindParameter_WithModelBinderType_NonGreedy_NoData() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderType = typeof(NullResultModelBinder) }, ParameterType = typeof(Person2) }; // No data is passed. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState.Keys); }
public override ParameterDescriptor[] GetContextConstructorParameters(IConnectionInfo cxInfo) { var providerNameParameter = new ParameterDescriptor("providerName", "System.String"); var connectionStringParameter = new ParameterDescriptor("connectionString", "System.String"); return new[] { providerNameParameter, connectionStringParameter }; }
public async Task BindProperty_WithData_GetsBound(bool fallBackScenario) { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(Person) }; var prefix = fallBackScenario ? string.Empty : "Parameter1"; var queryStringKey = fallBackScenario ? "Token" : prefix + "." + "Token"; // any valid base64 string var expectedValue = new byte[] { 12, 13 }; var value = Convert.ToBase64String(expectedValue); var operationContext = ModelBindingTestHelper.GetOperationBindingContext( request => { request.QueryString = QueryString.Create(queryStringKey, value); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Token); Assert.Equal(expectedValue, boundPerson.Token); // ModelState Assert.True(modelState.IsValid); Assert.Equal(2, modelState.Keys.Count); Assert.Single(modelState.Keys, k => k == prefix); Assert.Single(modelState.Keys, k => k == queryStringKey); var key = Assert.Single(modelState.Keys, k => k == queryStringKey + "[0]"); Assert.NotNull(modelState[key].Value); // should be non null bug #2445. Assert.Empty(modelState[key].Errors); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); key = Assert.Single(modelState.Keys, k => k == queryStringKey + "[1]"); Assert.NotNull(modelState[key].Value); // should be non null bug #2445. Assert.Empty(modelState[key].Errors); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); }
public void Bind_should_invoke_internal_DataBinder_using_values_from_Request_Params() { var http = new Mock<HttpContextBase>(); var attr = new DataBindAttribute(); var descriptor = new ParameterDescriptor("user", typeof (User)); http.SetupGet(ctx => ctx.Request.Params).Returns(new NameValueCollection{{"user.Name", "Lyle"}}); var result = attr.Bind(http.Object, descriptor); Assert.IsAssignableFrom<User>(result); Assert.AreEqual("Lyle", ((User) result).Name); }
public static object GetValue(Command cmd, ParameterDescriptor pd) { object value = null; if (pd.SourceLocation == SourceLocation.FromCommand) { value = cmd.Arguments[pd.KeyInSource]; } else { throw new Exception("Unknow SourceLocation"); } return value; }
public async Task BindProperty_WithData_WithPrefix_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", }, ParameterType = typeof(Person) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = QueryString.Create("CustomParameter.Address.Zip", "1"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Address); Assert.Equal(1, boundPerson.Address.Zip); // ModelState Assert.True(modelState.IsValid); Assert.Equal(1, modelState.Keys.Count); var key = Assert.Single(modelState.Keys, k => k == "CustomParameter.Address.Zip"); Assert.NotNull(modelState[key].Value); Assert.Equal("1", modelState[key].Value.AttemptedValue); Assert.Equal("1", modelState[key].Value.RawValue); Assert.NotNull(modelState[key].Value); Assert.Empty(modelState[key].Errors); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); }
public async Task BindProperty_WithData_WithEmptyPrefix_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(Person) }; var data = "Some Data Is Better Than No Data."; var operationContext = ModelBindingTestHelper.GetOperationBindingContext( request => { request.QueryString = QueryString.Create("Address.Zip", "12345"); UpdateRequest(request, data, "Address.File"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson.Address); var formCollection = Assert.IsAssignableFrom<FormCollection>(boundPerson.Address.FileCollection); var file = Assert.Single(formCollection.Files); Assert.Equal("form-data; name=Address.File; filename=text.txt", file.ContentDisposition); var reader = new StreamReader(file.OpenReadStream()); Assert.Equal(data, reader.ReadToEnd()); // ModelState Assert.True(modelState.IsValid); Assert.Equal(2, modelState.Count); Assert.Single(modelState.Keys, k => k == "Address.Zip"); var key = Assert.Single(modelState.Keys, k => k == "Address.File"); Assert.NotNull(modelState[key].Value); // should be non null bug #2445. Assert.Empty(modelState[key].Errors); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); }
public async Task BindPropertyFromHeader_WithPrefix_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "prefix", }, ParameterType = typeof(Person) }; // Do not add any headers. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.Headers.Add("Header", new[] { "someValue" }); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Address); Assert.Equal("someValue", boundPerson.Address.Street); // ModelState Assert.True(modelState.IsValid); Assert.Equal(3, modelState.Count); Assert.Single(modelState.Keys, k => k == "prefix.Address"); Assert.Single(modelState.Keys, k => k == "prefix"); var key = Assert.Single(modelState.Keys, k => k == "prefix.Address.Header"); Assert.NotNull(modelState[key].Value); Assert.Equal("someValue", modelState[key].Value.RawValue); Assert.Equal("someValue", modelState[key].Value.AttemptedValue); }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection<ParameterDescriptor> parameters = new Collection<ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters); Collection<FunctionDescriptor> functions = new Collection<FunctionDescriptor>(); functions.Add(function); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute<TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function JobHostConfiguration config = new JobHostConfiguration() { TypeLocator = new TypeLocator(functionType) }; config.UseTimers(); JobHost host = new JobHost(config); await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }
public async Task BindProperty_WithData__WithPrefix_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", }, ParameterType = typeof(Person) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(httpContext => { }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); Assert.NotNull(boundPerson.Token); // ModelState Assert.True(modelState.IsValid); Assert.Equal(2, modelState.Keys.Count); Assert.Single(modelState.Keys, k => k == "CustomParameter"); var key = Assert.Single(modelState.Keys, k => k == "CustomParameter.Token"); Assert.Null(modelState[key].Value); Assert.Empty(modelState[key].Errors); // This Assert Fails. Assert.Equal(ModelValidationState.Skipped, modelState[key].ValidationState); }
public async Task MutableObjectModelBinder_BindsNestedPOCO_WithBodyModelBinder_WithPrefix_Success() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Order1) }; // Need to have a key here so that the MutableObjectModelBinder will recurse to bind elements. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?parameter.Customer.Name=bill"); SetJsonBodyContent(request, AddressBodyContent); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType<Order1>(modelBindingResult.Model); Assert.NotNull(model.Customer); Assert.Equal("bill", model.Customer.Name); Assert.NotNull(model.Customer.Address); Assert.Equal(AddressStreetContent, model.Customer.Address.Street); Assert.Equal(2, modelState.Count); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value; Assert.Equal("bill", entry.Value.AttemptedValue); Assert.Equal("bill", entry.Value.RawValue); // These fail due to #2445 entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Address").Value; Assert.Null(entry.Value.AttemptedValue); // ModelState entries for body don't include original text. Assert.Same(model.Customer.Address, entry.Value.RawValue); }
public async Task DictionaryModelBinder_BindsDictionaryOfSimpleType_WithExplicitPrefix_Success() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", BindingInfo = new BindingInfo() { BinderModelName = "prefix", }, ParameterType = typeof(Dictionary<string, int>) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?prefix[0].Key=key0&prefix[0].Value=10"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType<Dictionary<string, int>>(modelBindingResult.Model); Assert.Equal(new Dictionary<string, int>() { { "key0", 10 }, }, model); Assert.Equal(2, modelState.Count); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0].Key").Value; Assert.Equal("key0", entry.Value.AttemptedValue); Assert.Equal("key0", entry.Value.RawValue); entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0].Value").Value; Assert.Equal("10", entry.Value.AttemptedValue); Assert.Equal("10", entry.Value.RawValue); }
public async Task ArrayModelBinder_BindsArrayOfSimpleType_WithPrefix_Success() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(int[]) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?parameter[0]=10¶meter[1]=11"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType<int[]>(modelBindingResult.Model); Assert.Equal(new int[] { 10, 11 }, model); Assert.Equal(2, modelState.Count); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0]").Value; Assert.Equal("10", entry.Value.AttemptedValue); Assert.Equal("10", entry.Value.RawValue); entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1]").Value; Assert.Equal("11", entry.Value.AttemptedValue); Assert.Equal("11", entry.Value.RawValue); }
public async Task BindPropertyFromHeader_NoData_UsesFullPathAsKeyForModelStateErrors() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", }, ParameterType = typeof(Person) }; // Do not add any headers. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); // ModelState Assert.False(modelState.IsValid); var key = Assert.Single(modelState.Keys); Assert.Equal("CustomParameter.Address.Header", key); var error = Assert.Single(modelState[key].Errors); // Mono issue - https://github.com/aspnet/External/issues/19 Assert.Equal(PlatformNormalizer.NormalizeContent("The Street field is required."), error.ErrorMessage); }
public async Task FromBodyAndRequiredOnProperty_EmptyBody_AddsModelStateError() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderModelName = "CustomParameter", }, ParameterType = typeof(Person) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext( request => { request.Body = new MemoryStream(Encoding.UTF8.GetBytes(string.Empty)); request.ContentType = "application/json"; }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var boundPerson = Assert.IsType<Person>(modelBindingResult.Model); Assert.NotNull(boundPerson); var key = Assert.Single(modelState.Keys); Assert.Equal("CustomParameter.Address", key); Assert.False(modelState.IsValid); var error = Assert.Single(modelState[key].Errors); // Mono issue - https://github.com/aspnet/External/issues/19 Assert.Equal(PlatformNormalizer.NormalizeContent("The Address field is required."), error.ErrorMessage); }
public async Task Validation_RequiredAttribute_OnSimpleTypeProperty_NoData() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Order1) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType<Order1>(modelBindingResult.Model); Assert.Null(model.CustomerName); Assert.Equal(1, modelState.Count); Assert.Equal(1, modelState.ErrorCount); Assert.False(modelState.IsValid); var entry = Assert.Single(modelState, e => e.Key == "CustomerName").Value; Assert.Null(entry.Value); Assert.Equal(ModelValidationState.Invalid, entry.ValidationState); var error = Assert.Single(entry.Errors); AssertRequiredError("CustomerName", error); }
public void Options_UseCorrectName_Returns_CorrectValue( string propertyName, string expectedOptionTemplate, string expectedOptionDescription, int expectedCommandOptionType, string commandLineStringWithTheOption, object expectedValueWhenOptionIsPresent, object expectedValueWhenOptionIsNotPresent) { //Arrange var command = new CommandLineApplication(); var property = typeof(TestClass).GetProperty(propertyName); var descriptor = new ParameterDescriptor(property); var expectedOption = new CommandOption(expectedOptionTemplate, (CommandOptionType)expectedCommandOptionType); //Act descriptor.AddCommandLineParameterTo(command); //Assert var actualOption = command.Options.First(); Assert.Equal(expectedOption.LongName, actualOption.LongName); Assert.Equal(expectedOption.ShortName, actualOption.ShortName); Assert.Equal(expectedOption.OptionType, actualOption.OptionType); Assert.Equal(expectedOptionDescription, actualOption.Description); //Arrange command.Execute(new string[0] { }); //Assert Assert.Equal(expectedValueWhenOptionIsNotPresent, descriptor.Value); //Arrange command.Execute(commandLineStringWithTheOption.Split(' ')); //Assert Assert.Equal(expectedValueWhenOptionIsPresent, descriptor.Value); }
public async Task BindParameter_WithModelBinderType_NoData(Type modelBinderType, bool isModelSet) { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo() { BinderType = modelBinderType }, ParameterType = typeof(string) }; // No data is passed. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.Null(modelBindingResult.Model); Assert.Equal(isModelSet, modelBindingResult.IsModelSet); // ModelState Assert.True(modelState.IsValid); var key = Assert.Single(modelState.Keys); Assert.Equal("CustomParameter", key); Assert.Equal(0, modelState.ErrorCount); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); Assert.Null(modelState[key].Value); // value is only set if the custom model binder sets it. }
private void DoDefaultDataBind(ParameterDescriptor param, List<object> args, ControllerExecutionContext executionCtx) { var requestParams = executionCtx.HttpContext.Request.Params; string value; if (requestParams.AllKeys.Any(key => key == param.Name)) { value = requestParams[param.Name]; TryConvert(param, value, args); return; } if (executionCtx.RouteData.Values.ContainsKey(param.Name)) { value = (string) executionCtx.RouteData.Values[param.Name]; TryConvert(param, value, args); return; } if (typeof(HttpContextBase).IsAssignableFrom(param.Type)) { args.Add(executionCtx.HttpContext); return; } if (typeof(ControllerContext).IsAssignableFrom(param.Type)) { args.Add(executionCtx.ControllerContext); return; } args.Add(null); }
public async Task BindParameter_NoData_DoesNotGetBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(string) }; // No Data. var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.Null(modelBindingResult); // ModelState Assert.True(modelState.IsValid); Assert.Empty(modelState.Keys); }
internal static IEnumerable <IContainer> AllContainersFor(this IEnumerable <IContainer> containers, ParameterDescriptor parameterDescriptor) { return(containers.AllContainersFor(parameterDescriptor.ContainerCriteria)); }
public override Task <ModelBindingResult> BindModelAsync(ActionContext actionContext, IValueProvider valueProvider, ParameterDescriptor parameter, object value) { Descriptors.Add(parameter); if (_args.TryGetValue(parameter.Name, out var result)) { return(Task.FromResult(ModelBindingResult.Success(result))); } return(Task.FromResult(ModelBindingResult.Failed())); }
/// <summary> /// Initializes a new instance of the <see cref="MethodMemberDescriptor"/> class. /// </summary> /// <param name="methodBase">The MethodBase (MethodInfo or ConstructorInfo) got through reflection.</param> /// <param name="accessMode">The interop access mode.</param> /// <exception cref="System.ArgumentException">Invalid accessMode</exception> public MethodMemberDescriptor(MethodBase methodBase, InteropAccessMode accessMode = InteropAccessMode.Default) { CheckMethodIsCompatible(methodBase, true); IsConstructor = (methodBase is ConstructorInfo); this.MethodInfo = methodBase; bool isStatic = methodBase.IsStatic || IsConstructor; if (IsConstructor) { m_IsAction = false; } else { m_IsAction = ((MethodInfo)methodBase).ReturnType == typeof(void); } ParameterInfo[] reflectionParams = methodBase.GetParameters(); ParameterDescriptor[] parameters; if (this.MethodInfo.DeclaringType.IsArray) { m_IsArrayCtor = true; int rank = this.MethodInfo.DeclaringType.GetArrayRank(); parameters = new ParameterDescriptor[rank]; for (int i = 0; i < rank; i++) { parameters[i] = new ParameterDescriptor("idx" + i.ToString(), typeof(int)); } } else { parameters = reflectionParams.Select(pi => new ParameterDescriptor(pi)).ToArray(); } bool isExtensionMethod = (methodBase.IsStatic && parameters.Length > 0 && methodBase.GetCustomAttributes(typeof(ExtensionAttribute), false).Any()); base.Initialize(methodBase.Name, isStatic, parameters, isExtensionMethod); // adjust access mode if (Script.GlobalOptions.Platform.IsRunningOnAOT()) { accessMode = InteropAccessMode.Reflection; } if (accessMode == InteropAccessMode.Default) { accessMode = UserData.DefaultAccessMode; } if (accessMode == InteropAccessMode.HideMembers) { throw new ArgumentException("Invalid accessMode"); } if (parameters.Any(p => p.Type.IsByRef)) { accessMode = InteropAccessMode.Reflection; } this.AccessMode = accessMode; if (AccessMode == InteropAccessMode.Preoptimized) { ((IOptimizableDescriptor)this).Optimize(); } }
/* ---------------- Parameter Mappers --------------- */ public ValueMapperContext GetParameterMapperContext(ParameterDescriptor parameter, Type destinationType, object[] value) { return(new ValueMapperContext(Configuration, GetRequestContext(), parameter, value)); }
public ValigatorModelStateException(ParameterDescriptor parameterDescriptor, params ValidationError[] errors) { ParameterDescriptor = parameterDescriptor; ValidationErrors = errors; }
/// <summary> /// Binds a model specified by <paramref name="parameter"/> using <paramref name="value"/> as the initial value. /// </summary> /// <param name="actionContext">The <see cref="ActionContext"/>.</param> /// <param name="modelBinder">The <see cref="IModelBinder"/>.</param> /// <param name="valueProvider">The <see cref="IValueProvider"/>.</param> /// <param name="parameter">The <see cref="ParameterDescriptor"/></param> /// <param name="metadata">The <see cref="ModelMetadata"/>.</param> /// <param name="value">The initial model value.</param> /// <returns>The result of model binding.</returns> public virtual async Task <ModelBindingResult> BindModelAsync( ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, object value) { if (actionContext == null) { throw new ArgumentNullException(nameof(actionContext)); } if (modelBinder == null) { throw new ArgumentNullException(nameof(modelBinder)); } if (valueProvider == null) { throw new ArgumentNullException(nameof(valueProvider)); } if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (metadata == null) { throw new ArgumentNullException(nameof(metadata)); } if (parameter.BindingInfo?.RequestPredicate?.Invoke(actionContext) == false) { return(ModelBindingResult.Failed()); } var modelBindingContext = DefaultModelBindingContext.CreateBindingContext( actionContext, valueProvider, metadata, parameter.BindingInfo, parameter.Name); modelBindingContext.Model = value; Logger.AttemptingToBindParameterOrProperty(parameter, modelBindingContext); var parameterModelName = parameter.BindingInfo?.BinderModelName ?? metadata.BinderModelName; if (parameterModelName != null) { // The name was set explicitly, always use that as the prefix. modelBindingContext.ModelName = parameterModelName; } else if (modelBindingContext.ValueProvider.ContainsPrefix(parameter.Name)) { // We have a match for the parameter name, use that as that prefix. modelBindingContext.ModelName = parameter.Name; } else { // No match, fallback to empty string as the prefix. modelBindingContext.ModelName = string.Empty; } await modelBinder.BindModelAsync(modelBindingContext); Logger.DoneAttemptingToBindParameterOrProperty(parameter, modelBindingContext); var modelBindingResult = modelBindingContext.Result; if (_mvcOptions.AllowValidatingTopLevelNodes && _objectModelValidator is ObjectModelValidator baseObjectValidator) { Logger.AttemptingToValidateParameterOrProperty(parameter, modelBindingContext); EnforceBindRequiredAndValidate( baseObjectValidator, actionContext, parameter, metadata, modelBindingContext, modelBindingResult); Logger.DoneAttemptingToValidateParameterOrProperty(parameter, modelBindingContext); } else { // For legacy implementations (which directly implemented IObjectModelValidator), fall back to the // back-compatibility logic. In this scenario, top-level validation attributes will be ignored like // they were historically. if (modelBindingResult.IsModelSet) { _objectModelValidator.Validate( actionContext, modelBindingContext.ValidationState, modelBindingContext.ModelName, modelBindingResult.Model); } } return(modelBindingResult); }
protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { var parameterValue = base.GetParameterValue(controllerContext, parameterDescriptor); return(parameterValue); }
internal PseudoModelBindingVisitor(ApiParameterContext context, ParameterDescriptor parameter) { Context = context; Parameter = parameter; }
/// <summary> /// 获取参数的值。 /// </summary> /// <param name="controllerContext"></param> /// <param name="parameterDescriptor"></param> /// <returns></returns> protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { var type = parameterDescriptor.ParameterType.GetNonNullableType(); if (type.IsPrimitive || type.IsEnum || type == typeof(string)) { var value = controllerContext.HttpContext.Request.Params[parameterDescriptor.ParameterName]; if (value == "null") { return(null); } return(base.GetParameterValue(controllerContext, parameterDescriptor)); } else { //对json进行反序列化,由于使用了基于 Fireasy AOP 的实体模型,所以必须使用 Fireasy 的反序列化方法 var json = controllerContext.HttpContext.Request.Params[parameterDescriptor.ParameterName]; if (!string.IsNullOrEmpty(json)) { try { var option = new JsonSerializeOption(); var globalconverters = GlobalSetting.Converters.Where(s => s is JsonConverter).Cast <JsonConverter>(); option.Converters.AddRange(globalconverters); var serializer = ContainerUnity.GetContainer().TryGetService <ISerializer>(() => new JsonSerializer(option)); if (serializer is ITextSerializer txtSerializer) { return(txtSerializer.Deserialize(json, parameterDescriptor.ParameterType)); } else { return(serializer.Deserialize(Encoding.UTF8.GetBytes(json), parameterDescriptor.ParameterType)); } } catch (Exception exp) { var logger = LoggerFactory.CreateLogger(); if (logger != null) { var message = string.Format("无法解析控制器 {0} 的方法 {1} 的参数 {2} 的值。\n\n数据为: {3}", parameterDescriptor.ActionDescriptor.ControllerDescriptor.ControllerName, parameterDescriptor.ActionDescriptor.ActionName, parameterDescriptor.ParameterName, json); logger.Error(message, exp); } } } return(null); } }
public BindingBase(AttributeCloner <TAttribute> cloner, ParameterDescriptor param) { Cloner = cloner; _param = param; }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // Get the Type Attributes (in this case, a TimeoutAttribute) ScriptHostConfiguration scriptConfig = new ScriptHostConfiguration(); scriptConfig.FunctionTimeout = TimeSpan.FromMinutes(5); Collection <CustomAttributeBuilder> typeAttributes = ScriptHost.CreateTypeAttributes(scriptConfig); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); TimeoutAttribute timeoutAttribute = (TimeoutAttribute)functionType.GetCustomAttributes().Single(); Assert.Equal(TimeSpan.FromMinutes(5), timeoutAttribute.Timeout); Assert.True(timeoutAttribute.ThrowOnTimeout); Assert.True(timeoutAttribute.TimeoutWhileDebugging); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute <TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function JobHostConfiguration config = new JobHostConfiguration() { TypeLocator = new TypeLocator(functionType) }; config.UseTimers(); JobHost host = new JobHost(config); await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }
public async Task DictionaryModelBinder_BindsDictionaryOfComplexType_EmptyPrefix_Success() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Dictionary<string, Person>) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?[0].Key=key0&[0].Value.Id=10"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); var model = Assert.IsType<Dictionary<string, Person>>(modelBindingResult.Model); Assert.Equal(1, model.Count); Assert.Equal("key0", model.Keys.First()); Assert.Equal(model.Values, model.Values); Assert.Equal(2, modelState.Count); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); // Fails due to #2470 var entry = Assert.Single(modelState, kvp => kvp.Key == "[0].Key").Value; Assert.Equal("key0", entry.Value.AttemptedValue); Assert.Equal("key0", entry.Value.RawValue); entry = Assert.Single(modelState, kvp => kvp.Key == "[0].Value.Id").Value; Assert.Equal("10", entry.Value.AttemptedValue); Assert.Equal("10", entry.Value.RawValue); }
protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { if (parameterDescriptor.ParameterType == typeof(IUnitOfWork) || parameterDescriptor.ParameterType == typeof(IDbConnection)) { return(null); } return(base.GetParameterValue(controllerContext, parameterDescriptor)); }
public DescribedMvcActionParameterInfo(ParameterDescriptor paramDescr, ActionInfo action) : base(action) { this.paramDescr = paramDescr; this.reflectedParamDescr = paramDescr as ReflectedParameterDescriptor; }
public ContainerParameterData(ParameterDescriptor parameter, PropertyInfo property) { Parameter = parameter; Property = property; }
/// <summary> /// Fills the member list. /// </summary> private void FillMemberList() { HashSet <string> membersToIgnore = new HashSet <string>( Framework.Do.GetCustomAttributes(this.Type, typeof(MoonSharpHideMemberAttribute), true) .OfType <MoonSharpHideMemberAttribute>() .Select(a => a.MemberName) ); Type type = this.Type; if (AccessMode == InteropAccessMode.HideMembers) { return; } if (!type.IsDelegateType()) { // add declared constructors foreach (ConstructorInfo ci in Framework.Do.GetConstructors(type)) { if (membersToIgnore.Contains("__new")) { continue; } AddMember("__new", MethodMemberDescriptor.TryCreateIfVisible(ci, this.AccessMode)); } // valuetypes don't reflect their empty ctor.. actually empty ctors are a perversion, we don't care and implement ours if (Framework.Do.IsValueType(type) && !membersToIgnore.Contains("__new")) { AddMember("__new", new ValueTypeDefaultCtorMemberDescriptor(type)); } } // add methods to method list and metamethods foreach (MethodInfo mi in Framework.Do.GetMethods(type)) { if (membersToIgnore.Contains(mi.Name)) { continue; } MethodMemberDescriptor md = MethodMemberDescriptor.TryCreateIfVisible(mi, this.AccessMode); if (md != null) { if (!MethodMemberDescriptor.CheckMethodIsCompatible(mi, false)) { continue; } // transform explicit/implicit conversions to a friendlier name. string name = mi.Name; if (mi.IsSpecialName && (mi.Name == SPECIALNAME_CAST_EXPLICIT || mi.Name == SPECIALNAME_CAST_IMPLICIT)) { name = mi.ReturnType.GetConversionMethodName(); } AddMember(name, md); foreach (string metaname in mi.GetMetaNamesFromAttributes()) { AddMetaMember(metaname, md); } } } // get properties foreach (PropertyInfo pi in Framework.Do.GetProperties(type)) { if (pi.IsSpecialName || pi.GetIndexParameters().Any() || membersToIgnore.Contains(pi.Name)) { continue; } AddMember(pi.Name, PropertyMemberDescriptor.TryCreateIfVisible(pi, this.AccessMode)); } // get fields foreach (FieldInfo fi in Framework.Do.GetFields(type)) { if (fi.IsSpecialName || membersToIgnore.Contains(fi.Name)) { continue; } AddMember(fi.Name, FieldMemberDescriptor.TryCreateIfVisible(fi, this.AccessMode)); } // get events foreach (EventInfo ei in Framework.Do.GetEvents(type)) { if (ei.IsSpecialName || membersToIgnore.Contains(ei.Name)) { continue; } AddMember(ei.Name, EventMemberDescriptor.TryCreateIfVisible(ei, this.AccessMode)); } // get nested types and create statics foreach (Type nestedType in Framework.Do.GetNestedTypes(type)) { if (membersToIgnore.Contains(nestedType.Name)) { continue; } if (!Framework.Do.IsGenericTypeDefinition(nestedType)) { if (Framework.Do.IsNestedPublic(nestedType) || Framework.Do.GetCustomAttributes(nestedType, typeof(MoonSharpUserDataAttribute), true).Length > 0) { var descr = UserData.RegisterType(nestedType, this.AccessMode); if (descr != null) { AddDynValue(nestedType.Name, UserData.CreateStatic(nestedType)); } } } } if (!membersToIgnore.Contains("[this]")) { if (Type.IsArray) { int rank = Type.GetArrayRank(); ParameterDescriptor[] get_pars = new ParameterDescriptor[rank]; ParameterDescriptor[] set_pars = new ParameterDescriptor[rank + 1]; for (int i = 0; i < rank; i++) { get_pars[i] = set_pars[i] = new ParameterDescriptor("idx" + i.ToString(), typeof(int)); } set_pars[rank] = new ParameterDescriptor("value", Type.GetElementType()); AddMember(SPECIALNAME_INDEXER_SET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_SET, true, set_pars)); AddMember(SPECIALNAME_INDEXER_GET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_GET, false, get_pars)); } else if (Type == typeof(Array)) { AddMember(SPECIALNAME_INDEXER_SET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_SET, true)); AddMember(SPECIALNAME_INDEXER_GET, new ArrayMemberDescriptor(SPECIALNAME_INDEXER_GET, false)); } } }
public async Task ObsoleteBindModelAsync_PassesExpectedBindingInfoAndMetadata_IfPrefixDoesNotMatch( BindingInfo parameterBindingInfo, string metadataBinderModelName, string parameterName, string expectedModelName) { // Arrange var binderExecuted = false; var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForType <Person>().BindingDetails(binding => { binding.BinderModelName = metadataBinderModelName; }); var metadata = metadataProvider.GetMetadataForType(typeof(Person)); var modelBinder = new Mock <IModelBinder>(); modelBinder .Setup(b => b.BindModelAsync(It.IsAny <ModelBindingContext>())) .Callback((ModelBindingContext context) => { Assert.Equal(expectedModelName, context.ModelName, StringComparer.Ordinal); }) .Returns(Task.CompletedTask); var parameterDescriptor = new ParameterDescriptor { BindingInfo = parameterBindingInfo, Name = parameterName, ParameterType = typeof(Person), }; var factory = new Mock <IModelBinderFactory>(MockBehavior.Strict); factory .Setup(f => f.CreateBinder(It.IsAny <ModelBinderFactoryContext>())) .Callback((ModelBinderFactoryContext context) => { binderExecuted = true; // Confirm expected data is passed through to ModelBindingFactory. Assert.Same(parameterDescriptor.BindingInfo, context.BindingInfo); Assert.Same(parameterDescriptor, context.CacheToken); Assert.Equal(metadata, context.Metadata); }) .Returns(modelBinder.Object); var parameterBinder = new ParameterBinder( metadataProvider, factory.Object, Mock.Of <IObjectModelValidator>(), _optionsAccessor, NullLoggerFactory.Instance); var controllerContext = GetControllerContext(); // Act & Assert #pragma warning disable CS0618 // Type or member is obsolete await parameterBinder.BindModelAsync(controllerContext, new SimpleValueProvider(), parameterDescriptor); #pragma warning restore CS0618 // Type or member is obsolete Assert.True(binderExecuted); }
public static ExactBinding <TMessage> TryBuild( AsyncCollectorBindingProvider <TAttribute, TType> parent, Mode mode, BindingProviderContext context) { var patternMatcher = parent._patternMatcher; var parameter = context.Parameter; TAttribute attributeSource = parameter.GetCustomAttribute <TAttribute>(inherit: false); Func <TAttribute, Task <TAttribute> > hookWrapper = null; if (parent.PostResolveHook != null) { hookWrapper = (attrResolved) => parent.PostResolveHook(attrResolved, parameter, parent._nameResolver); } Func <object, object> buildFromAttribute; FuncConverter <TMessage, TAttribute, TType> converter = null; // Prefer the shortest route to creating the user type. // If TType matches the user type directly, then we should be able to directly invoke the builder in a single step. // TAttribute --> TUserType var checker = ConverterManager.GetTypeValidator <TType>(); if (checker.IsMatch(typeof(TMessage))) { buildFromAttribute = patternMatcher.TryGetConverterFunc( typeof(TAttribute), typeof(IAsyncCollector <TMessage>)); } else { var converterManager = parent._converterManager; // Try with a converter // Find a builder for : TAttribute --> TType // and then couple with a converter: TType --> TParameterType converter = converterManager.GetConverter <TMessage, TType, TAttribute>(); if (converter == null) { // Preserves legacy behavior. This means we can only have 1 async collector. // However, the collector's builder object can switch. throw NewMissingConversionError(typeof(TMessage)); } buildFromAttribute = patternMatcher.TryGetConverterFunc( typeof(TAttribute), typeof(IAsyncCollector <TType>)); } if (buildFromAttribute == null) { return(null); } ParameterDescriptor param; if (parent.BuildParameterDescriptor != null) { param = parent.BuildParameterDescriptor(attributeSource, parameter, parent._nameResolver); } else { param = new ParameterDescriptor { Name = parameter.Name, DisplayHints = new ParameterDisplayHints { Description = "output" } }; } var cloner = new AttributeCloner <TAttribute>(attributeSource, context.BindingDataContract, parent._nameResolver, hookWrapper); return(new ExactBinding <TMessage>(cloner, param, mode, buildFromAttribute, converter)); }
public async Task BindModelAsync_ForOverlappingParametersWithSuppressions_InValid_WithInValidSecondParameter() { // Arrange var parameterDescriptor = new ParameterDescriptor { Name = "patchDocument", ParameterType = typeof(IJsonPatchDocument), }; var actionContext = GetControllerContext(); var modelState = actionContext.ModelState; // First ModelState key is not empty to match SimpleTypeModelBinder. modelState.SetModelValue("id", "notAGuid", "notAGuid"); modelState.AddModelError("id", "This is not valid."); // Second ModelState key is empty to match BodyModelBinder. modelState.AddModelError(string.Empty, "This is also not valid."); var modelMetadataProvider = new TestModelMetadataProvider(); modelMetadataProvider.ForType <IJsonPatchDocument>().ValidationDetails(v => v.ValidateChildren = false); var modelMetadata = modelMetadataProvider.GetMetadataForType(typeof(IJsonPatchDocument)); var parameterBinder = new ParameterBinder( modelMetadataProvider, Mock.Of <IModelBinderFactory>(), new DefaultObjectValidator( modelMetadataProvider, new[] { TestModelValidatorProvider.CreateDefaultProvider() }, new MvcOptions()), _optionsAccessor, NullLoggerFactory.Instance); var modelBindingResult = ModelBindingResult.Failed(); var modelBinder = CreateMockModelBinder(modelBindingResult); // Act var result = await parameterBinder.BindModelAsync( actionContext, modelBinder, new SimpleValueProvider(), parameterDescriptor, modelMetadata, value : null); // Assert Assert.False(result.IsModelSet); Assert.False(modelState.IsValid); Assert.Collection( modelState, kvp => { Assert.Empty(kvp.Key); Assert.Equal(ModelValidationState.Invalid, kvp.Value.ValidationState); var error = Assert.Single(kvp.Value.Errors); Assert.Equal("This is also not valid.", error.ErrorMessage); }, kvp => { Assert.Equal("id", kvp.Key); Assert.Equal(ModelValidationState.Invalid, kvp.Value.ValidationState); var error = Assert.Single(kvp.Value.Errors); Assert.Equal("This is not valid.", error.ErrorMessage); }); }
public static Parameter AsModel(this ParameterDescriptor descriptor) { return(new Parameter(descriptor)); }
void UpdateBindingInfo(ActionParameterContext context, ParameterDescriptor parameter) { Contract.Requires(context != null); Contract.Requires(parameter != null); var parameterType = parameter.ParameterType; var bindingInfo = parameter.BindingInfo; if (bindingInfo != null) { if ((parameterType.IsODataQueryOptions() || parameterType.IsODataPath()) && bindingInfo.BindingSource == Custom) { bindingInfo.BindingSource = Special; } return; } var metadata = ModelMetadataProvider.GetMetadataForType(parameterType); parameter.BindingInfo = bindingInfo = new BindingInfo() { BindingSource = metadata.BindingSource }; if (bindingInfo.BindingSource != null) { if ((parameterType.IsODataQueryOptions() || parameterType.IsODataPath()) && bindingInfo.BindingSource == Custom) { bindingInfo.BindingSource = Special; } return; } var key = default(IEdmNamedElement); var paramName = parameter.Name; var source = Query; switch (context.RouteContext.ActionType) { case EntitySet: var keys = context.RouteContext.EntitySet.EntityType().Key().ToArray(); key = keys.FirstOrDefault(k => k.Name.Equals(paramName, OrdinalIgnoreCase)); if (key == null) { var template = context.PathTemplate; if (template != null) { var segments = template.Segments.OfType <KeySegmentTemplate>(); if (segments.SelectMany(s => s.ParameterMappings.Values).Any(name => name.Equals(paramName, OrdinalIgnoreCase))) { source = Path; } } } else { source = Path; } break; case BoundOperation: case UnboundOperation: var operation = context.RouteContext.Operation; if (operation == null) { break; } key = operation.Parameters.FirstOrDefault(p => p.Name.Equals(paramName, OrdinalIgnoreCase)); if (key == null) { if (operation.IsBound) { goto case EntitySet; } } else { source = Path; } break; } bindingInfo.BindingSource = source; parameter.BindingInfo = bindingInfo; }
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 BindParameter_NonConvertibleValue_GetsCustomErrorMessage() { // Arrange var parameterType = typeof(int); var metadataProvider = new TestModelMetadataProvider(); metadataProvider .ForType(parameterType) .BindingDetails(binding => { // A real details provider could customize message based on BindingMetadataProviderContext. binding.ModelBindingMessageProvider.SetNonPropertyAttemptedValueIsInvalidAccessor( (value) => $"Hmm, '{ value }' is not a valid value."); }); var testContext = ModelBindingTestHelper.GetTestContext( request => { request.QueryString = QueryString.Create("Parameter1", "abcd"); }, metadataProvider: metadataProvider); var modelState = testContext.ModelState; var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = parameterType }; // Act var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); // Assert // ModelBindingResult Assert.False(modelBindingResult.IsModelSet); // Model Assert.Null(modelBindingResult.Model); // ModelState Assert.False(modelState.IsValid); Assert.Single(modelState); Assert.Equal(1, modelState.ErrorCount); var key = Assert.Single(modelState.Keys); Assert.Equal("Parameter1", key); var entry = modelState[key]; Assert.Equal("abcd", entry.RawValue); Assert.Equal("abcd", entry.AttemptedValue); Assert.Equal(ModelValidationState.Invalid, entry.ValidationState); var error = Assert.Single(entry.Errors); Assert.Null(error.Exception); Assert.Equal($"Hmm, 'abcd' is not a valid value.", error.ErrorMessage); }
public void Should_not_apply_to_complex_types(ParameterDescriptor parameter) { new SimpleTypeMapper().AppliesTo(new ValueMapperContext( null, null, parameter, null)).ShouldBeFalse(); }
public static ExactBinding <TUserType> TryBuild( BindToInputBindingProvider <TAttribute, TType> parent, BindingProviderContext context) { var cm = parent._converterManager; var patternMatcher = parent._patternMatcher; var parameter = context.Parameter; TAttribute attributeSource = parameter.GetCustomAttribute <TAttribute>(inherit: false); Func <TAttribute, Task <TAttribute> > hookWrapper = null; if (parent.PostResolveHook != null) { hookWrapper = (attrResolved) => parent.PostResolveHook(attrResolved, parameter, parent._nameResolver); } var cloner = new AttributeCloner <TAttribute>(attributeSource, context.BindingDataContract, parent._nameResolver, hookWrapper); Func <object, object> buildFromAttribute; FuncConverter <TType, TAttribute, TUserType> converter = null; // Prefer the shortest route to creating the user type. // If TType matches the user type directly, then we should be able to directly invoke the builder in a single step. // TAttribute --> TUserType var checker = ConverterManager.GetTypeValidator <TType>(); if (checker.IsMatch(typeof(TUserType))) { buildFromAttribute = patternMatcher.TryGetConverterFunc(typeof(TAttribute), typeof(TUserType)); } else { // Try with a converter // Find a builder for : TAttribute --> TType // and then couple with a converter: TType --> TParameterType converter = cm.GetConverter <TType, TUserType, TAttribute>(); if (converter == null) { return(null); } buildFromAttribute = patternMatcher.TryGetConverterFunc(typeof(TAttribute), typeof(TType)); } if (buildFromAttribute == null) { return(null); } ParameterDescriptor param; if (parent.BuildParameterDescriptor != null) { param = parent.BuildParameterDescriptor(attributeSource, parameter, parent._nameResolver); } else { param = new ParameterDescriptor { Name = parameter.Name, DisplayHints = new ParameterDisplayHints { Description = "input" } }; } return(new ExactBinding <TUserType>(cloner, param, buildFromAttribute, converter)); }
public async Task BindParameter_WithData_GetsBound() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "Parameter1", BindingInfo = new BindingInfo(), ParameterType = typeof(string) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = QueryString.Create("Parameter1", "someValue"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert // ModelBindingResult Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); // Model var model = Assert.IsType<string>(modelBindingResult.Model); Assert.Equal("someValue", model); // ModelState Assert.True(modelState.IsValid); Assert.Equal(1, modelState.Keys.Count); var key = Assert.Single(modelState.Keys); Assert.Equal("Parameter1", key); Assert.NotNull(modelState[key].Value); Assert.Equal("someValue", modelState[key].Value.AttemptedValue); Assert.Equal("someValue", modelState[key].Value.RawValue); Assert.Empty(modelState[key].Errors); Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState); }
protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { try { controllerContext.RouteData.DataTokens.Add(typeof(ParameterDescriptor).FullName, parameterDescriptor); return(base.GetParameterValue(controllerContext, parameterDescriptor)); } finally { controllerContext.RouteData.DataTokens.Remove(typeof(ParameterDescriptor).FullName); } }
public NameValueParameterBinding(ParameterDescriptor parameterDescriptor) : base(parameterDescriptor) { }
public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw Error.ArgumentNull("bindingContext"); } HttpRequest request = bindingContext.HttpContext.Request; if (request == null) { throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest); } ActionDescriptor actionDescriptor = bindingContext.ActionContext.ActionDescriptor; if (actionDescriptor == null) { throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor); } // Get the parameter description of the parameter to bind. ParameterDescriptor paramDescriptor = bindingContext.ActionContext.ActionDescriptor.Parameters .Where(p => p.Name == bindingContext.FieldName) .FirstOrDefault(); // Now make sure parameter type is ODataQueryOptions or ODataQueryOptions<T>. Type parameterType = paramDescriptor?.ParameterType; if (IsODataQueryOptions(parameterType)) { // Get the entity type from the parameter type if it is ODataQueryOptions<T>. // Fall back to the return type if not. Also, note that the entity type from the return type and ODataQueryOptions<T> // can be different (example implementing $select or $expand). Type entityClrType = null; if (paramDescriptor != null) { entityClrType = GetEntityClrTypeFromParameterType(parameterType); } if (entityClrType == null) { entityClrType = GetEntityClrTypeFromActionReturnType(actionDescriptor); } IEdmModel userModel = request.GetModel(); IEdmModel model = userModel != EdmCoreModel.Instance ? userModel : actionDescriptor.GetEdmModel(request, entityClrType); ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType, request.ODataFeature().Path); Func <ODataQueryContext, HttpRequest, ODataQueryOptions> createODataQueryOptions; object constructorAsObject = null; if (actionDescriptor.Properties.TryGetValue(CreateODataQueryOptionsCtorKey, out constructorAsObject)) { createODataQueryOptions = (Func <ODataQueryContext, HttpRequest, ODataQueryOptions>)constructorAsObject; } else { createODataQueryOptions = (Func <ODataQueryContext, HttpRequest, ODataQueryOptions>) Delegate.CreateDelegate(typeof(Func <ODataQueryContext, HttpRequest, ODataQueryOptions>), _createODataQueryOptions.MakeGenericMethod(entityClrType)); }; ODataQueryOptions parameterValue = createODataQueryOptions(entitySetContext, request); bindingContext.Result = ModelBindingResult.Success(parameterValue); } return(TaskHelpers.Completed()); }
public async Task DictionaryModelBinder_BindsDictionaryOfComplexType_NoData() { // Arrange var argumentBinder = ModelBindingTestHelper.GetArgumentBinder(); var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(Dictionary<string, Person>) }; var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request => { request.QueryString = new QueryString("?"); }); var modelState = new ModelStateDictionary(); // Act var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext); // Assert Assert.NotNull(modelBindingResult); Assert.True(modelBindingResult.IsModelSet); Assert.Empty(Assert.IsType<Dictionary<string, Person>>(modelBindingResult.Model)); Assert.Equal(0, modelState.Count); Assert.Equal(0, modelState.ErrorCount); Assert.True(modelState.IsValid); }
public async Task Generate_EndToEnd() { // construct our TimerTrigger attribute ([TimerTrigger("00:00:02", RunOnStartup = true)]) Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>(); ParameterDescriptor parameter = new ParameterDescriptor("timerInfo", typeof(TimerInfo)); ConstructorInfo ctorInfo = typeof(TimerTriggerAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo runOnStartupProperty = typeof(TimerTriggerAttribute).GetProperty("RunOnStartup"); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder( ctorInfo, new object[] { "00:00:02" }, new PropertyInfo[] { runOnStartupProperty }, new object[] { true }); parameter.CustomAttributes.Add(attributeBuilder); parameters.Add(parameter); // create the FunctionDefinition FunctionMetadata metadata = new FunctionMetadata(); TestInvoker invoker = new TestInvoker(); FunctionDescriptor function = new FunctionDescriptor("TimerFunction", invoker, metadata, parameters, null, null, null); Collection <FunctionDescriptor> functions = new Collection <FunctionDescriptor>(); functions.Add(function); // Get the Type Attributes (in this case, a TimeoutAttribute) ScriptJobHostOptions scriptConfig = new ScriptJobHostOptions(); scriptConfig.FunctionTimeout = TimeSpan.FromMinutes(5); Collection <CustomAttributeBuilder> typeAttributes = new Collection <CustomAttributeBuilder>(); // generate the Type Type functionType = FunctionGenerator.Generate("TestScriptHost", "TestFunctions", typeAttributes, functions); // verify the generated function MethodInfo method = functionType.GetMethod("TimerFunction"); ParameterInfo triggerParameter = method.GetParameters()[0]; TimerTriggerAttribute triggerAttribute = triggerParameter.GetCustomAttribute <TimerTriggerAttribute>(); Assert.NotNull(triggerAttribute); // start the JobHost which will start running the timer function var builder = new HostBuilder() .ConfigureWebJobs(b => { b.AddTimers() .AddAzureStorageCoreServices(); }) .ConfigureServices(s => { s.AddSingleton <ITypeLocator>(new TestTypeLocator(functionType)); s.AddSingleton <ILoggerFactory>(new LoggerFactory()); }); using (var host = builder.Build()) { await host.StartAsync(); await Task.Delay(3000); await host.StopAsync(); } // verify our custom invoker was called Assert.True(invoker.InvokeCount >= 2); }
/// <summary> /// Returns names and types of parameters that should be passed into the data context constructor. /// </summary> /// <param name="cxInfo"> Connection information, as entered by the user. </param> /// <returns> Names and types of parameters that should be passed into the data context constructor. </returns> public override ParameterDescriptor[] GetContextConstructorParameters(IConnectionInfo cxInfo) { var parameter = new ParameterDescriptor("playback", typeof(Playback).FullName); return(new[] { parameter }); }
public Parameter(ParameterDescriptor descriptor) : base(descriptor.ParameterType) { Descriptor = descriptor; }