Beispiel #1
0
    /// <summary>
    /// Initializes the specified field of component to all instances of some type, given then information in bindAttribute.
    /// </summary>
    /// <param name="field">Field to bind</param>
    /// <param name="bindAttribute">Information about how to bind it</param>
    /// <param name="component">Object with the field</param>
    /// <param name="elementType">Element type of the field to be bound</param>
    private static void BindArrayField(FieldInfo field, BindAttribute bindAttribute, MonoBehaviour component, Type elementType)
    {
        Object[] target = null;
        switch (bindAttribute.Scope)
        {
        case BindingScope.GameObject:
            // ReSharper disable CoVariantArrayConversion
            target = component.GetComponents(elementType);
            // ReSharper restore CoVariantArrayConversion
            break;

        case BindingScope.GameObjectOrChildren:
            // ReSharper disable CoVariantArrayConversion
            target = component.GetComponentsInChildren(elementType);
            // ReSharper restore CoVariantArrayConversion
            break;

        case BindingScope.Global:
            target = FindObjectsOfType(elementType);
            break;
        }
#if LogBinding
        Debug.Log(string.Format("Binding {0}.{1}.{2} to {3} elements", component.gameObject.name, component.GetType().Name, field.Name, target.Length));
#endif
        field.SetValue(component, target);
    }
Beispiel #2
0
        public void BindAttribute_ProviderType_Cached()
        {
            // Arrange
            var bind = new BindAttribute(typeof(TestProvider));

            var context = new DefaultModelBindingContext();

            context.OperationBindingContext = new OperationBindingContext()
            {
                ActionContext = new ActionContext()
                {
                    HttpContext = new DefaultHttpContext(),
                },
            };

            var services = new Mock <IServiceProvider>(MockBehavior.Strict);

            context.OperationBindingContext.HttpContext.RequestServices = services.Object;

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.True(predicate(context, "UserName"));
            Assert.True(predicate(context, "UserName"));
        }
        /// <summary>
        ///     Reflect into the routeValueObject and remove any keys from
        ///     routeValues that are not bound by the Bind attribute
        /// </summary>
        private static void RemoveUnboundValues(RouteValueDictionary routeValues
                                                , object source)
        {
            if (source == null)
            {
                return;
            }

            Type type = source.GetType();

            BindAttribute b = type.GetCustomAttributes(true).OfType <BindAttribute>().FirstOrDefault();

            if (b == null)
            {
                return;
            }

            foreach (PropertyInfo property in type.GetProperties())
            {
                string propertyName = property.Name;
                if (!b.IsPropertyAllowed(propertyName))
                {
                    routeValues.Remove(propertyName);
                }
            }
        }
        // add property filter described by BindAttribute, override prefix
        protected override object BindCslaModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (string.IsNullOrEmpty(BindCriteria.Include) && string.IsNullOrEmpty(BindCriteria.Exclude) && string.IsNullOrEmpty(BindCriteria.Prefix))
            {
                return(base.BindCslaModel(controllerContext, bindingContext));
            }

            Predicate <string> propFilter = bindingContext.PropertyFilter;

            if (!string.IsNullOrEmpty(BindCriteria.Include) || !string.IsNullOrEmpty(BindCriteria.Exclude))
            {
                var bindAttr = new BindAttribute()
                {
                    Exclude = BindCriteria.Exclude, Include = BindCriteria.Include
                };
                propFilter = (propName) => bindAttr.IsPropertyAllowed(propName) &&
                             bindingContext.PropertyFilter(propName);
            }

            var newPrefix = BindCriteria.Prefix ?? bindingContext.ModelName;

            var newBindingContext = new ModelBindingContext()
            {
                Model          = bindingContext.Model,
                ModelName      = newPrefix,
                ModelState     = bindingContext.ModelState,
                ModelType      = bindingContext.ModelType,
                PropertyFilter = propFilter,
                ValueProvider  = bindingContext.ValueProvider
            };

            return(base.BindCslaModel(controllerContext, newBindingContext));
        }
Beispiel #5
0
        private string GetTargetName(
            Option <BindingConfig> bindingConfig,
            TypePair typePair,
            MemberInfo sourceMember,
            Dictionary <string, string> targetBindings)
        {
            Option <string>      targetName;
            List <BindAttribute> binds = sourceMember.GetAttributes <BindAttribute>();
            BindAttribute        bind  = binds.FirstOrDefault(x => x.TargetType.IsNull());

            if (bind.IsNull())
            {
                bind = binds.FirstOrDefault(x => typePair.Target.IsAssignableFrom(x.TargetType));
            }
            if (bind.IsNotNull())
            {
                targetName = new Option <string>(bind.MemberName);
            }
            else
            {
                targetName = bindingConfig.Map(x => x.GetBindField(sourceMember.Name));
                if (targetName.HasNoValue)
                {
                    if (targetBindings.TryGetValue(sourceMember.Name, out var targetMemberName))
                    {
                        targetName = new Option <string>(targetMemberName);
                    }
                    else
                    {
                        targetName = new Option <string>(sourceMember.Name);
                    }
                }
            }
            return(targetName.Value);
        }
Beispiel #6
0
        public void BindAttribute_ProviderType(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(typeof(TestProvider));

            var context = new ModelBindingContext();

            context.OperationBindingContext = new OperationBindingContext()
            {
                HttpContext = new DefaultHttpContext(),
            };

            var activator = new Mock <ITypeActivator>(MockBehavior.Strict);

            activator
            .Setup(a => a.CreateInstance(It.IsAny <IServiceProvider>(), typeof(TestProvider), It.IsAny <object[]>()))
            .Returns(new TestProvider())
            .Verifiable();

            var services = new Mock <IServiceProvider>(MockBehavior.Strict);

            services
            .Setup(s => s.GetService(typeof(ITypeActivator)))
            .Returns(activator.Object);

            context.OperationBindingContext.HttpContext.RequestServices = services.Object;

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, predicate(context, property));
        }
        public void PrefixProperty()
        {
            // Arrange
            BindAttribute attr = new BindAttribute { Prefix = "somePrefix" };

            // Act & assert
            Assert.Equal("somePrefix", attr.Prefix);
        }
        public void ExcludePropertyDefaultsToEmptyString()
        {
            // Arrange
            BindAttribute attr = new BindAttribute { Exclude = null };

            // Act & assert
            Assert.Equal(String.Empty, attr.Exclude);
        }
Beispiel #9
0
        public void Constructor_SetsThe_PropertyFilterProviderType_ForValidTypes(Type type)
        {
            // Arrange
            var attribute = new BindAttribute(type);

            // Act & Assert
            Assert.Equal(type, attribute.PredicateProviderType);
        }
Beispiel #10
0
        public void Constructor_SetsThe_PropertyFilterProviderType_ForValidTypes(Type type)
        {
            // Arrange
            var attribute = new BindAttribute(type);

            // Act & Assert
            Assert.Equal(type, attribute.PredicateProviderType);
        }
        public void PrefixPropertyDefaultsToNull()
        {
            // Arrange
            BindAttribute attr = new BindAttribute();

            // Act & assert
            Assert.Null(attr.Prefix);
        }
        public void PrefixPropertyDefaultsToNull()
        {
            // Arrange
            BindAttribute attr = new BindAttribute();

            // Act & assert
            Assert.IsNull(attr.Prefix);
        }
Beispiel #13
0
    /// <summary>
    /// Initializes the specified field of component to all instances of some type, given then information in bindAttribute.
    /// </summary>
    /// <param name="field">Field to bind</param>
    /// <param name="bindAttribute">Information about how to bind it</param>
    /// <param name="component">Object with the field</param>
    /// <param name="elementType">Element type of the field to be bound</param>
    // ReSharper disable UnusedParameter.Local
    private static void BindListField(FieldInfo field, BindAttribute bindAttribute, MonoBehaviour component, Type elementType)
    // ReSharper restore UnusedParameter.Local
    {
        System.Diagnostics.Debug.Assert(bindAttribute.Scope == BindingScope.Global);
#if LogBinding
        Debug.Log(string.Format("Binding {0}.{1}.{2} to {3} elements", component.gameObject.name, component.GetType().Name, field.Name, Registry(elementType).Count));
#endif
        field.SetValue(component, Registry(elementType));
    }
        public void IsPropertyAllowedReturnsTrueAlwaysIfBindPropertiesIsAll()
        {
            // Setup
            BindAttribute attr = new BindAttribute();

            // Act & assert
            Assert.True(attr.IsPropertyAllowed("foo"));
            Assert.True(attr.IsPropertyAllowed("bar"));
            Assert.True(attr.IsPropertyAllowed("baz"));
        }
        public void IsPropertyAllowedReturnsFalseForBlacklistedPropertiesIfBindPropertiesIsExclude()
        {
            // Setup
            BindAttribute attr = new BindAttribute { Exclude = "FOO,BAZ" };

            // Act & assert
            Assert.False(attr.IsPropertyAllowed("foo"));
            Assert.True(attr.IsPropertyAllowed("bar"));
            Assert.False(attr.IsPropertyAllowed("baz"));
        }
        public void IsPropertyAllowedReturnsTrueAlwaysIfBindPropertiesIsAll()
        {
            // Setup
            BindAttribute attr = new BindAttribute();

            // Act & assert
            Assert.IsTrue(attr.IsPropertyAllowed("foo"));
            Assert.IsTrue(attr.IsPropertyAllowed("bar"));
            Assert.IsTrue(attr.IsPropertyAllowed("baz"));
        }
        public void ExcludePropertyDefaultsToEmptyString()
        {
            // Arrange
            BindAttribute attr = new BindAttribute {
                Exclude = null
            };

            // Act & assert
            Assert.AreEqual(String.Empty, attr.Exclude);
        }
        public void IsPropertyAllowedReturnsTrueForWhitelistedPropertiesIfBindPropertiesIsInclude()
        {
            // Setup
            BindAttribute attr = new BindAttribute { Include = "FOO,BAR" };

            // Act & assert
            Assert.True(attr.IsPropertyAllowed("foo"));
            Assert.True(attr.IsPropertyAllowed("bar"));
            Assert.False(attr.IsPropertyAllowed("baz"));
        }
        public void PrefixProperty()
        {
            // Arrange
            BindAttribute attr = new BindAttribute {
                Prefix = "somePrefix"
            };

            // Act & assert
            Assert.AreEqual("somePrefix", attr.Prefix);
        }
        private void ReadSettingsFromBindAttribute(BindAttribute bindAttribute)
        {
            if (bindAttribute == null)
            {
                return;
            }

            ExcludedProperties = SplitString(bindAttribute.Exclude).ToList();
            IncludedProperties = SplitString(bindAttribute.Include).ToList();
        }
        private Predicate <string> GetPropertyFilter(ParameterDescriptor parameterDescriptor)
        {
            ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo;
            var ba = new BindAttribute()
            {
                Exclude = string.Join(",", bindingInfo.Exclude),
                Include = string.Join(",", bindingInfo.Include)
            };

            return(ba.IsPropertyAllowed);
        }
        public void IsPropertyAllowedReturnsTrueForWhitelistedPropertiesIfBindPropertiesIsInclude()
        {
            // Setup
            BindAttribute attr = new BindAttribute {
                Include = "FOO,BAR"
            };

            // Act & assert
            Assert.IsTrue(attr.IsPropertyAllowed("foo"));
            Assert.IsTrue(attr.IsPropertyAllowed("bar"));
            Assert.IsFalse(attr.IsPropertyAllowed("baz"));
        }
        public void IsPropertyAllowedReturnsFalseForBlacklistedPropertiesIfBindPropertiesIsExclude()
        {
            // Setup
            BindAttribute attr = new BindAttribute {
                Exclude = "FOO,BAZ"
            };

            // Act & assert
            Assert.False(attr.IsPropertyAllowed("foo"));
            Assert.True(attr.IsPropertyAllowed("bar"));
            Assert.False(attr.IsPropertyAllowed("baz"));
        }
        public void IsPropertyAllowedReturnsFalseForBlacklistOverridingWhitelistedProperties()
        {
            // Setup
            BindAttribute attr = new BindAttribute {
                Include = "FOO,BAR", Exclude = "bar,QUx"
            };

            // Act & assert
            Assert.IsTrue(attr.IsPropertyAllowed("foo"));
            Assert.IsFalse(attr.IsPropertyAllowed("bar"));
            Assert.IsFalse(attr.IsPropertyAllowed("baz"));
            Assert.IsFalse(attr.IsPropertyAllowed("qux"));
        }
Beispiel #25
0
        public void BindAttribute_Include(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(new string[] { "UserName", "FirstName" });

            var context = new ModelBindingContext();

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, predicate(context, property));
        }
Beispiel #26
0
        public void BindAttribute_Include(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(new string[] { "UserName", "FirstName", "LastName, MiddleName,  ,foo,bar " });

            var context = new ModelBindingContext();

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, predicate(context, property));
        }
Beispiel #27
0
        protected void ProtectsFromOverposting(Controller controller, String postMethod, String properties)
        {
            MethodInfo methodInfo = controller
                                    .GetType()
                                    .GetMethods()
                                    .First(method =>
                                           method.Name == postMethod &&
                                           method.IsDefined(typeof(HttpPostAttribute), false));

            BindAttribute actual = methodInfo
                                   .GetParameters()
                                   .First()
                                   .GetCustomAttribute <BindAttribute>(false);

            Assert.Equal(properties, actual.Exclude);
        }
Beispiel #28
0
    public void GetBindingInfo_ReadsPropertyPredicateProvider()
    {
        // Arrange
        var bindAttribute = new BindAttribute(include: "SomeProperty");
        var attributes    = new object[]
        {
            bindAttribute,
        };

        // Act
        var bindingInfo = BindingInfo.GetBindingInfo(attributes);

        // Assert
        Assert.NotNull(bindingInfo);
        Assert.Same(bindAttribute, bindingInfo.PropertyFilterProvider);
    }
        public void BindAttribute_Include(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(new string[] { "UserName", "FirstName", "LastName, MiddleName,  ,foo,bar " });

            var context = new DefaultModelBindingContext();

            var identity = ModelMetadataIdentity.ForProperty(typeof(int), property, typeof(string));

            context.ModelMetadata = new Mock <ModelMetadata>(identity).Object;

            // Act
            var propertyFilter = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, propertyFilter(context.ModelMetadata));
        }
Beispiel #30
0
        internal ModelBindingContext CreateComplexElementalModelBindingContext(ControllerContext controllerContext, ModelBindingContext bindingContext, object model)
        {
            BindAttribute      bindAttr          = (BindAttribute)GetTypeDescriptor(controllerContext, bindingContext).GetAttributes()[typeof(BindAttribute)];
            Predicate <string> newPropertyFilter = (bindAttr != null)
                ? propertyName => bindAttr.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName)
                : bindingContext.PropertyFilter;

            ModelBindingContext newBindingContext = new ModelBindingContext()
            {
                ModelMetadata  = ModelMetadataProviders.Current.GetMetadataForType(() => model, bindingContext.ModelType),
                ModelName      = bindingContext.ModelName,
                ModelState     = bindingContext.ModelState,
                PropertyFilter = newPropertyFilter,
                ValueProvider  = bindingContext.ValueProvider
            };

            return(newBindingContext);
        }
        protected virtual IEnumerable <ModelMetadata> GetMetadataForProperties(ModelBindingContext bindingContext)
        {
            var validationInfo       = GetPropertyValidationInfo(bindingContext);
            var propertyTypeMetadata = bindingContext.MetadataProvider
                                       .GetMetadataForType(null, bindingContext.ModelType);
            Predicate <string> newPropertyFilter =
                propertyName => bindingContext.PropertyFilter(propertyName) &&
                BindAttribute.IsPropertyAllowed(
                    propertyName,
                    propertyTypeMetadata.IncludedProperties,
                    propertyTypeMetadata.ExcludedProperties);

            return(bindingContext.ModelMetadata.Properties
                   .Where(propertyMetadata =>
                          newPropertyFilter(propertyMetadata.PropertyName) &&
                          (validationInfo.RequiredProperties.Contains(propertyMetadata.PropertyName) ||
                           !validationInfo.SkipProperties.Contains(propertyMetadata.PropertyName)) &&
                          CanUpdateProperty(propertyMetadata)));
        }
Beispiel #32
0
        public void BindAttribute_ProviderType(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(typeof(TestProvider));

            var context = new ModelBindingContext();
            context.OperationBindingContext = new OperationBindingContext()
            {
                HttpContext = new DefaultHttpContext(),
            };
            var services = new Mock<IServiceProvider>();

            context.OperationBindingContext.HttpContext.RequestServices = services.Object;

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, predicate(context, property));
        }
Beispiel #33
0
        public void BindAttribute_ProviderType(string property, bool isIncluded)
        {
            // Arrange
            var bind = new BindAttribute(typeof(TestProvider));

            var context = new ModelBindingContext();

            context.OperationBindingContext = new OperationBindingContext()
            {
                HttpContext = new DefaultHttpContext(),
            };
            var services = new Mock <IServiceProvider>();

            context.OperationBindingContext.HttpContext.RequestServices = services.Object;

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.Equal(isIncluded, predicate(context, property));
        }
Beispiel #34
0
    /// <summary>
    /// Initializes the specified field of component given then information in bindAttribute.
    /// </summary>
    /// <param name="field">Field to bind</param>
    /// <param name="bindAttribute">Information about how to bind it</param>
    /// <param name="component">Object with the field</param>
    private static void BindSimpleField(FieldInfo field, BindAttribute bindAttribute, MonoBehaviour component)
    {
        Object target = null;

        switch (bindAttribute.Scope)
        {
        case BindingScope.GameObject:
            target = component.GetComponent(field.FieldType);
            break;

        case BindingScope.GameObjectOrChildren:
            target = component.GetComponentInChildren(field.FieldType);
            break;

        case BindingScope.Global:
            target = FindObjectOfType(field.FieldType);
            break;
        }

        if (target == null)
        {
            switch (bindAttribute.IfNotFound)
            {
            case BindingDefault.Exception:
                throw new Exception(string.Format("{0}.{1}.{2}: no target to bind to", component.gameObject.name, component.GetType().Name, field.Name));

            case BindingDefault.Create:
                target = component.gameObject.AddComponent(field.FieldType);
                break;

            case BindingDefault.Ignore:
                break;
            }
        }

#if LogBinding
        Debug.Log(string.Format("Binding {0}.{1}.{2} to {3}", component.gameObject.name, component.GetType().Name, field.Name, target));
#endif
        field.SetValue(component, target);
    }
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //POST PUT 方法进行模型校验
            string method = context.HttpContext.Request.Method;

            if ((method == "POST" || method == "PUT") && !context.ModelState.IsValid)
            {
                //BindAttribute特性对JSON数据无效
                IList <ParameterDescriptor> parameterDescriptors = context.ActionDescriptor.Parameters;
                //获取BindAttribute
                ParameterDescriptor parameterDescriptor = parameterDescriptors.Where(item => item.BindingInfo.PropertyFilterProvider is BindAttribute).SingleOrDefault();

                BindAttribute bindAttribute = parameterDescriptor.BindingInfo.PropertyFilterProvider as BindAttribute;

                string message = context.ModelState.ToErrorMessageByBindAttribute(bindAttribute);

                if (message != string.Empty)
                {
                    ResponseResult responseResult = CommonFactory.CreateResponseResult;
                    context.Result = new JsonResult(responseResult.Failed(message));
                    return;
                }
            }
        }
Beispiel #36
0
        internal static List <IPatchBase> ReadPatchDocumentProperties <T>(JsonReader reader, string path,
                                                                          BindAttribute bindAttribute        = null, Action <JsonReader> patchTypeAction = null,
                                                                          Action <IPatchPrimitive> keyAction = null)
        {
            if (reader == null)
            {
                return(null);
            }

            var          modelTypeAssemblyName = typeof(T).AssemblyQualifiedName;
            bool         cacheProperties;
            const string patchTypeKey = PatchArrayDocument <object> .PatchTypeKey;

            // ReSharper disable once AssignmentInConditionalExpression
            var modelProperties = (cacheProperties = PropertyInfos.All(x => x.Key.Key1 != modelTypeAssemblyName))
                ? typeof(T).GetTypeInfo().GetProperties()
                : PropertyInfos.Where(x => x.Key.Key1 == modelTypeAssemblyName).Select(x => x.Value).ToArray();

            var values    = new List <IPatchBase>();
            var startPath = reader.Path;

            bindAttribute = bindAttribute ?? typeof(T).GetAttribute <BindAttribute>();
            path          = string.IsNullOrWhiteSpace(path) ? string.Empty : path + ".";

            var keys = new List <IPatchPrimitive>();

            while (reader.Read())
            {
                if (reader.Path == startPath)
                {
                    break;
                }

                if (reader.TokenType != JsonToken.PropertyName)
                {
                    while (reader.Read())
                    {
                        if (reader.Path == startPath)
                        {
                            return(null);
                        }
                    }
                }

                var readerValueAsName = (string)reader.Value;

                if (readerValueAsName == patchTypeKey)
                {
                    if (patchTypeAction != null)
                    {
                        patchTypeAction(reader);
                    }
                    else
                    {
                        reader.Skip();
                    }

                    continue;
                }

                var propertyInfo = modelProperties.FirstOrDefault(x =>
                {
                    var jsonPropertyNameAttribute = x.GetCustomAttribute <JsonPropertyAttribute>();

                    if (jsonPropertyNameAttribute != null)
                    {
                        return(string.Equals(jsonPropertyNameAttribute.PropertyName, readerValueAsName));
                    }

                    return(readerValueAsName.Equals(new CamelCaseNamingStrategy().GetPropertyName(x.Name, false)) ||
                           readerValueAsName.Equals(x.Name) ||
                           readerValueAsName.Equals(new SnakeCaseNamingStrategy().GetPropertyName(x.Name, false)));
                });

                // If property not found, we should report an error with it.
                if (propertyInfo == null)
                {
                    values.Add(new PatchPrimitive <object>
                    {
                        Errors = new List <Error>
                        {
                            new Error
                            {
                                ErrorType = typeof(InvalidCastException),
                                JsonName  = readerValueAsName,
                                JsonPath  = reader.Path,
                                Message   = string.Format(Resources.UnknownProperty, readerValueAsName),
                                Name      = readerValueAsName,
                                Path      = reader.Path
                            }
                        },
                        Found    = true,
                        JsonName = readerValueAsName,
                        JsonPath = reader.Path,
                        Name     = readerValueAsName,
                        Path     = reader.Path,
                        Value    = null
                    });

                    // Since this is an unknown property, we should not parse it.
                    reader.Skip();

                    continue;
                }

                var propertyName = propertyInfo.Name;
                var isKey        = propertyInfo.GetCustomAttribute <KeyAttribute>() != null;
                var isBindable   = IsBindable(bindAttribute, propertyName);

                if (!isBindable && (!isKey || keyAction == null))
                {
                    reader.Skip();
                    continue;
                }

                var value = (IPatchBase)SelectStrategyMethodInfo.MakeGenericMethod(propertyInfo.PropertyType)
                            .Invoke(null, new object[] { reader, propertyName, path + propertyName, propertyInfo });

                value.IgnoreApply = propertyInfo.GetCustomAttribute <IgnorePatchAttribute>() != null;

                if (isKey && keyAction != null)
                {
                    keys.Add((IPatchPrimitive)value);
                }

                if (isBindable)
                {
                    values.Add(value);
                }
            }

            foreach (var propertyInfo in modelProperties)
            {
                if (cacheProperties)
                {
                    PropertyInfos.Add(modelTypeAssemblyName, propertyInfo.Name, propertyInfo);
                }

                if (values.Any(x => x.Name == propertyInfo.Name))
                {
                    continue;
                }

                var propertyName = propertyInfo.Name;
                var isKey        = propertyInfo.GetCustomAttribute <KeyAttribute>() != null;
                var isBindable   = IsBindable(bindAttribute, propertyName);

                if (!isBindable && (!isKey || keyAction == null))
                {
                    continue;
                }

                var value = (IPatchBase)SelectStrategyMethodInfo.MakeGenericMethod(propertyInfo.PropertyType)
                            .Invoke(null, new object[] { null, propertyName, path + propertyName, propertyInfo });

                value.IgnoreApply = propertyInfo.GetCustomAttribute <IgnorePatchAttribute>() != null;

                if (isKey && keyAction != null && keys.All(x => x.Name != value.Name))
                {
                    keys.Add((IPatchPrimitive)value);
                }

                if (isBindable)
                {
                    values.Add(value);
                }
            }

            if (keys.Any())
            {
                foreach (var key in keys)
                {
                    // ReSharper disable once PossibleNullReferenceException
                    keyAction.Invoke(key);
                }
            }

            return(values);
        }
Beispiel #37
0
        internal static IPatchArrayDocument <T> ReadArrayDocument <T>(JsonReader reader, string name, string path,
                                                                      BindAttribute bindAttribute = null)
        {
            var jsonPath = reader.Path;
            var jsonName = !string.IsNullOrWhiteSpace(jsonPath) ? jsonPath.Split('.').Last() : jsonPath;

            var          errors         = new List <Error>();
            var          patchKeys      = new List <IPatchPrimitive>();
            var          patchTypeFound = false;
            PatchTypes?  patchType      = null;
            const string patchTypeKey   = PatchArrayDocument <object> .PatchTypeKey;

            var values = reader.TokenType == JsonToken.StartObject
                ? ReadPatchDocumentProperties <T>(reader, path, bindAttribute,
                                                  patchKeyReader =>
            {
                try
                {
                    patchTypeFound = true;

                    var patchKeyAsInt = patchKeyReader.ReadAsInt32();

                    patchType = Enum.IsDefined(typeof(PatchTypes), patchKeyAsInt)
                                ? (PatchTypes?)patchKeyAsInt
                                : null;

                    if (patchType == null)
                    {
                        errors.Add(new Error
                        {
                            ErrorKind = ErrorKinds.ApplyToUpdate,
                            ErrorType = typeof(InvalidCastException),
                            JsonName  = patchTypeKey,
                            JsonPath  = $"{jsonPath}.{patchTypeKey}",
                            Message   = Resources.InvalidCast,
                            Name      = patchTypeKey,
                            Path      = $"{path}.{patchTypeKey}"
                        });
                    }
                }
                catch (Exception)
                {
                    reader.Skip();

                    errors.Add(new Error
                    {
                        ErrorKind = ErrorKinds.ApplyToUpdate,
                        ErrorType = typeof(InvalidCastException),
                        JsonName  = patchTypeKey,
                        JsonPath  = $"{jsonPath}.{patchTypeKey}",
                        Message   = Resources.InvalidCast,
                        Name      = patchTypeKey,
                        Path      = $"{path}.{patchTypeKey}"
                    });
                }
            },
                                                  x =>
            {
                if (patchType != null && patchType != PatchTypes.Add && !x.Found)
                {
                    errors.Add(new Error
                    {
                        ErrorKind = ErrorKinds.ApplyToUpdate,
                        ErrorType = typeof(RequiredAttribute),
                        JsonName  = x.JsonName,
                        JsonPath  = x.JsonPath,
                        Message   = string.Format(Resources.KeyNotFound, x.Name),
                        Name      = x.Name,
                        Path      = x.Path
                    });
                }

                patchKeys.Add(x);
            })
                : null;

            if (values != null)
            {
                //ToDo: Check for validations
                //errors.AddRange(Validate(name, jsonPath, validationAttributes, values, ErrorKinds.ApplyToAll));

                if (!patchTypeFound)
                {
                    errors.Add(new Error
                    {
                        ErrorKind = ErrorKinds.ApplyToUpdate,
                        ErrorType = typeof(RequiredAttribute),
                        JsonName  = patchTypeKey,
                        JsonPath  = $"{jsonPath}.{patchTypeKey}",
                        Message   = Resources.PatchTypeNotFound,
                        Name      = patchTypeKey,
                        Path      = $"{path}.{patchTypeKey}"
                    });
                }
            }
            else
            {
                values = new List <IPatchBase>();

                errors.Add(new Error
                {
                    ErrorKind = ErrorKinds.ApplyToUpdate,
                    ErrorType = typeof(InvalidCastException),
                    JsonName  = jsonName,
                    JsonPath  = jsonPath,
                    Message   = Resources.InvalidCast,
                    Name      = name,
                    Path      = path
                });
            }

            return(new PatchArrayDocument <T>
            {
                Errors = errors,
                JsonName = jsonName,
                JsonPath = jsonPath,
                Name = name,
                PatchKeys = patchKeys,
                PatchType = patchType,
                Path = path,
                Values = values
            });
        }
Beispiel #38
0
 /// <summary>
 /// Initializes the specified field of component to all instances of some type, given then information in bindAttribute.
 /// </summary>
 /// <param name="field">Field to bind</param>
 /// <param name="bindAttribute">Information about how to bind it</param>
 /// <param name="component">Object with the field</param>
 /// <param name="elementType">Element type of the field to be bound</param>
 // ReSharper disable UnusedParameter.Local
 private static void BindListField(FieldInfo field, BindAttribute bindAttribute, MonoBehaviour component, Type elementType)
 // ReSharper restore UnusedParameter.Local
 {
     System.Diagnostics.Debug.Assert(bindAttribute.Scope == BindingScope.Global);
     field.SetValue(component, Registry(elementType));
 }
Beispiel #39
0
    /// <summary>
    /// Initializes the specified field of component to all instances of some type, given then information in bindAttribute.
    /// </summary>
    /// <param name="field">Field to bind</param>
    /// <param name="bindAttribute">Information about how to bind it</param>
    /// <param name="component">Object with the field</param>
    /// <param name="elementType">Element type of the field to be bound</param>
    private static void BindArrayField(FieldInfo field, BindAttribute bindAttribute, MonoBehaviour component, Type elementType)
    {
        Object[] target = null;
        switch (bindAttribute.Scope)
        {
            case BindingScope.GameObject:
                // ReSharper disable CoVariantArrayConversion
                target = component.GetComponents(elementType);
                // ReSharper restore CoVariantArrayConversion
                break;

            case BindingScope.GameObjectOrChildren:
                // ReSharper disable CoVariantArrayConversion
                target = component.GetComponentsInChildren(elementType);
                // ReSharper restore CoVariantArrayConversion
                break;

            case BindingScope.Global:
                target = FindObjectsOfType(elementType);
                break;
        }

        field.SetValue(component, target);
    }
Beispiel #40
0
    /// <summary>
    /// Initializes the specified field of component given then information in bindAttribute.
    /// </summary>
    /// <param name="field">Field to bind</param>
    /// <param name="bindAttribute">Information about how to bind it</param>
    /// <param name="component">Object with the field</param>
    private static void BindSimpleField(FieldInfo field, BindAttribute bindAttribute, MonoBehaviour component)
    {
        Object target = null;
        switch (bindAttribute.Scope)
        {
            case BindingScope.GameObject:
                target = component.GetComponent(field.FieldType);
                break;

            case BindingScope.GameObjectOrChildren:
                target = component.GetComponentInChildren(field.FieldType);
                break;

            case BindingScope.Global:
                target = FindObjectOfType(field.FieldType);
                break;
        }

        if (target == null)
            switch (bindAttribute.IfNotFound)
            {
                case BindingDefault.Exception:
                    throw new Exception("No target to bind to");

                case BindingDefault.Create:
                    target = component.gameObject.AddComponent(field.FieldType);
                    break;

                case BindingDefault.Ignore:
                    break;
            }

        field.SetValue(component, target);
    }
        public void IsPropertyAllowedReturnsFalseForBlacklistOverridingWhitelistedProperties()
        {
            // Setup
            BindAttribute attr = new BindAttribute { Include = "FOO,BAR", Exclude = "bar,QUx" };

            // Act & assert
            Assert.True(attr.IsPropertyAllowed("foo"));
            Assert.False(attr.IsPropertyAllowed("bar"));
            Assert.False(attr.IsPropertyAllowed("baz"));
            Assert.False(attr.IsPropertyAllowed("qux"));
        }
Beispiel #42
0
        public void BindAttribute_ProviderType_Cached()
        {
            // Arrange
            var bind = new BindAttribute(typeof(TestProvider));

            var context = new ModelBindingContext();
            context.OperationBindingContext = new OperationBindingContext()
            {
                HttpContext = new DefaultHttpContext(),
            };

            var services = new Mock<IServiceProvider>(MockBehavior.Strict);

            context.OperationBindingContext.HttpContext.RequestServices = services.Object;

            // Act
            var predicate = bind.PropertyFilter;

            // Assert
            Assert.True(predicate(context, "UserName"));
            Assert.True(predicate(context, "UserName"));
        }
Beispiel #43
0
 public static bool IsBindable(BindAttribute attribute, string name)
 {
     return((attribute == null) || attribute.Include.Contains(name));
 }
Beispiel #44
0
        private IEnumerable <TModel> BindModelWithHtmlDocument <TModel>(IHtmlDocument htmlDocument, Action <TModel> postBindAction = null)
            where TModel : class, new()
        {
            Type modelType = typeof(TModel);

            BindAttribute bindAttribute = modelType.GetCustomAttributes <BindAttribute>(false).FirstOrDefault();

            if (bindAttribute == null)
            {
                throw new BindAttributeNotFoundException($"BindAttribute not found for model {modelType.FullName}");
            }

            // TODO : @deniz bunu genel bir yere taþýmak lazým. Birden fazla parametre olan durumlarda olucak
            string cssSelector = bindAttribute.CssSelector;

            if (string.IsNullOrEmpty(cssSelector))
            {
                throw new CssSelectorNotFoundException($"BindAttribute not found for model {modelType.FullName}");
            }

            if (CssSelectorParameters.Any(pair => cssSelector.Contains($"{{{pair.Key}}}")))
            {
                string key   = Regex.Match(cssSelector, @"\{([^}]*)\}").Groups[1].ToString();
                string value = CssSelectorParameters[key];

                cssSelector = cssSelector.Replace($"{{{key}}}", value);
            }

            IHtmlCollection <IElement> querySelectorAll = htmlDocument.QuerySelectorAll(cssSelector);

            List <TModel> models = new List <TModel>();

            foreach (IElement element in querySelectorAll)
            {
                TModel         instance      = Activator.CreateInstance <TModel>();
                PropertyInfo[] propertyInfos = modelType.GetProperties();

                // TODO : @deniz property info'lara neyin nasýl set edilecek Func<>'lar yazýlarak belirlenecek. Propert'nin attribute'üne göre property ve Func<> ikilisi oluþturulup, bu func'lar execute edilecek.
                // Performans için property info ve func'lar expression'a çevrilip cache'lene bilir, IL emiting yapýlabilir.

                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    var propertyBindAttribute = propertyInfo.GetCustomAttributes <BindAttribute>(false).FirstOrDefault();

                    if (propertyBindAttribute == null)
                    {
                        continue;
                    }

                    string elementValue;

                    IElement selectedElement = string.IsNullOrEmpty(propertyBindAttribute.CssSelector)
                        ? element
                        : propertyBindAttribute.ApplySelectorToHtmlDocument
                            ? htmlDocument.QuerySelector(propertyBindAttribute.CssSelector)
                            : element.QuerySelector(propertyBindAttribute.CssSelector);

                    if (!string.IsNullOrEmpty(propertyBindAttribute.AttributeName))
                    {
                        elementValue = selectedElement.Attributes[propertyBindAttribute.AttributeName].Value;
                    }
                    else
                    {
                        elementValue = propertyBindAttribute.ElementValueSelector == ElementValueSelector.InnerText
                            ? selectedElement.TextContent
                            : selectedElement.InnerHtml;
                    }

                    // TODO : @deniz Type conversion yapmak gerekebilir.
                    propertyInfo.SetValue(instance, elementValue);
                }

                postBindAction?.Invoke(instance);

                // TODO : yield return tarzý birþey kullanýlabilir
                models.Add(instance);
            }

            return(models);
        }