示例#1
0
        public void CopyConstructor_DoesDeepCopyOfOtherModels()
        {
            // Arrange
            var action = new ActionModel(typeof(TestController).GetMethod(nameof(TestController.Edit)),
                                         new List<object>());

            var parameter = new ParameterModel(action.ActionMethod.GetParameters()[0],
                                               new List<object>());
            parameter.Action = action;
            action.Parameters.Add(parameter);

            var route = new AttributeRouteModel(new HttpGetAttribute("api/Products"));
            action.Selectors.Add(new SelectorModel()
            {
                AttributeRouteModel = route
            });

            var apiExplorer = action.ApiExplorer;
            apiExplorer.IsVisible = false;
            apiExplorer.GroupName = "group1";

            // Act
            var action2 = new ActionModel(action);

            // Assert
            Assert.NotSame(action, action2.Parameters[0]);
            Assert.NotSame(apiExplorer, action2.ApiExplorer);
            Assert.NotSame(action.Selectors, action2.Selectors);
            Assert.NotNull(action2.Selectors);
            Assert.Single(action2.Selectors);
            Assert.NotSame(route, action2.Selectors[0].AttributeRouteModel);
        }
        private bool IsComplexTypeParameter(ParameterModel parameter)
        {
            // No need for information from attributes on the parameter. Just use its type.
            var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterInfo.ParameterType);

            return(metadata.IsComplexType);
        }
        /// <summary>
        /// Creates a <see cref="ParameterModel"/> for the given <see cref="ParameterInfo"/>.
        /// </summary>
        /// <param name="parameterInfo">The <see cref="ParameterInfo"/>.</param>
        /// <returns>A <see cref="ParameterModel"/> for the given <see cref="ParameterInfo"/>.</returns>
        internal ParameterModel CreateParameterModel(ParameterInfo parameterInfo)
        {
            if (parameterInfo == null)
            {
                throw new ArgumentNullException(nameof(parameterInfo));
            }

            var attributes = parameterInfo.GetCustomAttributes(inherit: true);

            BindingInfo bindingInfo;

            if (_modelMetadataProvider is ModelMetadataProvider modelMetadataProviderBase)
            {
                var modelMetadata = modelMetadataProviderBase.GetMetadataForParameter(parameterInfo);
                bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata);
            }
            else
            {
                // GetMetadataForParameter should only be used if the user has opted in to the 2.1 behavior.
                bindingInfo = BindingInfo.GetBindingInfo(attributes);
            }

            var parameterModel = new ParameterModel(parameterInfo, attributes)
            {
                ParameterName = parameterInfo.Name,
                BindingInfo   = bindingInfo,
            };

            return(parameterModel);
        }
示例#4
0
        /// <summary>
        /// Initializes a new <see cref="ParameterModel"/>.
        /// </summary>
        /// <param name="other">The parameter model to copy.</param>
        public ParameterModel(ParameterModel other)
            : base(other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            Action        = other.Action;
            ParameterInfo = other.ParameterInfo;
        }
        private static ParameterDescriptor CreateParameterDescriptor(ParameterModel parameterModel)
        {
            var parameterDescriptor = new ControllerParameterDescriptor()
            {
                Name          = parameterModel.ParameterName,
                ParameterType = parameterModel.ParameterInfo.ParameterType,
                BindingInfo   = parameterModel.BindingInfo,
                ParameterInfo = parameterModel.ParameterInfo,
            };

            return(parameterDescriptor);
        }
        private bool IsComplexTypeParameter(ParameterModel parameter)
        {
            // No need for information from attributes on the parameter. Just use its type.
            var metadata = _modelMetadataProvider
                           .GetMetadataForType(parameter.ParameterInfo.ParameterType);

            if (AllowInferringBindingSourceForCollectionTypesAsFromQuery && metadata.IsCollectionType)
            {
                return(false);
            }

            return(metadata.IsComplexType);
        }
示例#7
0
        // Internal for unit testing.
        internal BindingSource InferBindingSourceForParameter(ParameterModel parameter)
        {
            if (ParameterExistsInAnyRoute(parameter.Action, parameter.ParameterName))
            {
                return(BindingSource.Path);
            }

            var bindingSource = IsComplexTypeParameter(parameter) ?
                                BindingSource.Body :
                                BindingSource.Query;

            return(bindingSource);
        }
示例#8
0
        public ParameterModel(ParameterModel other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            Action        = other.Action;
            Attributes    = new List <object>(other.Attributes);
            BindingInfo   = other.BindingInfo == null ? null : new BindingInfo(other.BindingInfo);
            ParameterInfo = other.ParameterInfo;
            ParameterName = other.ParameterName;
            Properties    = new Dictionary <object, object>(other.Properties);
        }
示例#9
0
        public ParameterModel(ParameterModel other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            Action = other.Action;
            Attributes = new List<object>(other.Attributes);
            BindingInfo = other.BindingInfo == null ? null : new BindingInfo(other.BindingInfo);
            ParameterInfo = other.ParameterInfo;
            ParameterName = other.ParameterName;
            Properties = new Dictionary<object, object>(other.Properties);
        }
        public void OnProvidersExecuting_AppliesConventions()
        {
            // Arrange
            var controllerModel = new ControllerModel(typeof(TestApiController).GetTypeInfo(), new[] { new ApiControllerAttribute() })
            {
                Selectors = { new SelectorModel {
                                  AttributeRouteModel = new AttributeRouteModel()
                              } },
            };

            var method = typeof(TestApiController).GetMethod(nameof(TestApiController.TestAction));

            var actionModel = new ActionModel(method, Array.Empty <object>())
            {
                Controller = controllerModel,
            };

            controllerModel.Actions.Add(actionModel);

            var parameter      = method.GetParameters()[0];
            var parameterModel = new ParameterModel(parameter, Array.Empty <object>())
            {
                Action = actionModel,
            };

            actionModel.Parameters.Add(parameterModel);

            var context = new ApplicationModelProviderContext(new[] { controllerModel.ControllerType });

            context.Result.Controllers.Add(controllerModel);

            var provider = GetProvider();

            // Act
            provider.OnProvidersExecuting(context);

            // Assert
            // Verify some of the side-effects of executing API behavior conventions.
            Assert.True(actionModel.ApiExplorer.IsVisible);
            Assert.NotEmpty(actionModel.Filters.OfType <ModelStateInvalidFilterFactory>());
            Assert.NotEmpty(actionModel.Filters.OfType <ClientErrorResultFilterFactory>());
            Assert.Equal(BindingSource.Body, parameterModel.BindingInfo.BindingSource);
        }
示例#11
0
        public void CopyConstructor_DoesDeepCopyOfOtherModels()
        {
            // Arrange
            var action = new ActionModel(typeof(TestController).GetMethod(nameof(TestController.Edit)),
                                         new List <object>());

            var parameter = new ParameterModel(action.ActionMethod.GetParameters()[0],
                                               new List <object>());

            parameter.Action = action;
            action.Parameters.Add(parameter);

            var route = new AttributeRouteModel(new HttpGetAttribute("api/Products"));

            action.Selectors.Add(new SelectorModel()
            {
                AttributeRouteModel = route
            });

            var apiExplorer = action.ApiExplorer;

            apiExplorer.IsVisible = false;
            apiExplorer.GroupName = "group1";

            // Act
            var action2 = new ActionModel(action);

            // Assert
            Assert.NotSame(action.Parameters, action2.Parameters);
            Assert.NotNull(action2.Parameters);
            Assert.Single(action2.Parameters);
            Assert.NotSame(parameter, action2.Parameters[0]);
            Assert.NotSame(apiExplorer, action2.ApiExplorer);
            Assert.NotSame(action.Selectors, action2.Selectors);
            Assert.NotNull(action2.Selectors);
            Assert.Single(action2.Selectors);
            Assert.NotSame(action.Selectors[0], action2.Selectors[0]);
            Assert.NotSame(route, action2.Selectors[0].AttributeRouteModel);

            Assert.NotSame(action, action2.Parameters[0].Action);
            Assert.Same(action2, action2.Parameters[0].Action);
        }
 public void Apply(ParameterModel parameter)
 {
     parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
     parameter.BindingInfo.BinderModelName = "ChangedParameter";
 }
        public void CopyConstructor_CopiesAllProperties()
        {
            // Arrange
            var parameter = new ParameterModel(typeof(TestController).GetMethod("Edit").GetParameters()[0],
                                               new List <object>()
            {
                new FromBodyAttribute()
            });

            parameter.Action      = new ActionModel(typeof(TestController).GetMethod("Edit"), new List <object>());
            parameter.BindingInfo = new BindingInfo()
            {
                BindingSource = BindingSource.Body
            };

            parameter.ParameterName = "id";
            parameter.Properties.Add(new KeyValuePair <object, object>("test key", "test value"));

            // Act
            var parameter2 = new ParameterModel(parameter);

            // Assert
            foreach (var property in typeof(ParameterModel).GetProperties())
            {
                if (property.Name.Equals("BindingInfo"))
                {
                    // This test excludes other mutable objects on purpose because we deep copy them.
                    continue;
                }

                var value1 = property.GetValue(parameter);
                var value2 = property.GetValue(parameter2);

                if (typeof(IEnumerable <object>).IsAssignableFrom(property.PropertyType))
                {
                    Assert.Equal <object>((IEnumerable <object>)value1, (IEnumerable <object>)value2);

                    // Ensure non-default value
                    Assert.NotEmpty((IEnumerable <object>)value1);
                }
                else if (typeof(IDictionary <object, object>).IsAssignableFrom(property.PropertyType))
                {
                    Assert.Equal(value1, value2);

                    // Ensure non-default value
                    Assert.NotEmpty((IDictionary <object, object>)value1);
                }
                else if (property.PropertyType.GetTypeInfo().IsValueType ||
                         Nullable.GetUnderlyingType(property.PropertyType) != null)
                {
                    Assert.Equal(value1, value2);

                    // Ensure non-default value
                    Assert.NotEqual(value1, Activator.CreateInstance(property.PropertyType));
                }
                else
                {
                    Assert.Same(value1, value2);

                    // Ensure non-default value
                    Assert.NotNull(value1);
                }
            }
        }
        private bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter)
        {
            if (_configuration.Value.FormBodyBindingIgnoredTypes.Any(t => t.IsAssignableFrom(parameter.ParameterInfo.ParameterType)))
            {
                return false;
            }

            foreach (var selector in action.Selectors)
            {
                if (selector.ActionConstraints == null)
                {
                    continue;
                }

                foreach (var actionConstraint in selector.ActionConstraints)
                {
                    var httpMethodActionConstraint = actionConstraint as HttpMethodActionConstraint;
                    if (httpMethodActionConstraint == null)
                    {
                        continue;
                    }

                    if (httpMethodActionConstraint.HttpMethods.All(hm => hm.IsIn("GET", "DELETE", "TRACE", "HEAD")))
                    {
                        return false;
                    }
                }
            }

            return true;
        }
示例#15
0
 public void Apply(ParameterModel model)
 {
     model.BindingInfo = model.BindingInfo ?? new BindingInfo();
     model.BindingInfo.BindingSource = BindingSource.Custom;
     model.BindingInfo.BinderModelName = "CoolMetadata";
 }