Esempio n. 1
0
        private bool ValidateRecursive(object obj, bool throwException, int deepLevel)
        {
            const int maxDeepLevel = 100;

            // Prevent "StackOverflowException" (this should never happen)
            if (++deepLevel == maxDeepLevel)
            {
                throw new InvalidOperationException("Recursive function call exceeded the permitted deep level.");
            }

            // Validate all properties with "CommandParameterAttribute"
            foreach (var property in CommandParameterAttribute.GetOrderedProperties(obj))
            {
                // If property is value type and is not nullable, than must be set to nullable
                if (property.PropertyType.IsValueType && Nullable.GetUnderlyingType(property.PropertyType) == null)
                {
                    if (throwException)
                    {
                        throw new InvalidOperationException($"'{property.Name}' property must be nullable.");
                    }

                    return(false);
                }
            }

            // Validate all properties with attributes derived from "ValidationAttribute"
            var results = new List <ValidationResult>();

            Validator.TryValidateObject(obj, new ValidationContext(obj), results, true);

            if (results.Count > 0)
            {
                if (throwException)
                {
                    throw new ArgumentException(results[0].ToString());
                }

                return(false);
            }


            // Find all properties value with 'CommandBuilderObjectAttribute' and validate it recursively
            var properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (var property in properties)
            {
                var propertyValue = property.GetValue(obj);

                if (propertyValue == null)
                {
                    continue;
                }

                if (propertyValue.GetType().GetCustomAttribute <CommandBuilderObjectAttribute>() != null)
                {
                    ValidateRecursive(propertyValue, throwException, deepLevel);
                }
            }

            return(true);
        }
        private string BuildStringRecursive(object obj, int deepLevel)
        {
            const int maxDeepLevel = 100;

            // Prevent "StackOverflowException" (this should never happen)
            if (++deepLevel == maxDeepLevel)
            {
                throw new InvalidOperationException("Recursive function call exceeded the permitted deep level.");
            }


            var finalString = new StringBuilder();

            // Loop through all properties with "CommandParameterAttribute" attribute
            foreach (var property in CommandParameterAttribute.GetOrderedProperties(obj))
            {
                // Get property value
                var propertyValue = property.GetValue(obj);

                if (propertyValue == null)
                {
                    continue;
                }

                // Check if property value can be included in final command string
                if (!CanIncludeProperty(obj, property))
                {
                    continue;
                }

                // if property value has 'CommandBuilderObjectAttribute' then build string from it recursively
                if (propertyValue.GetType().GetCustomAttribute <CommandBuilderObjectAttribute>() != null)
                {
                    var value = BuildStringRecursive(propertyValue, deepLevel);

                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        finalString.Append($" {value}");
                    }

                    continue;
                }


                // Get "CommandParameterAttribute" from property
                var commandParameterAttribute = property.GetCustomAttribute <CommandParameterAttribute>();

                if (!commandParameterAttribute.RemoveWhiteSpaceBeforeValue)
                {
                    finalString.Append(" ");
                }

                var convertedPropertyValue = GetConvertedPropertyValue(obj, property);

                // If value format is set in "CommandParameterAttribute", then use it to format property value
                if (!string.IsNullOrWhiteSpace(commandParameterAttribute.Format))
                {
                    finalString.Append(string.Format(commandParameterAttribute.Format, convertedPropertyValue));
                }
                else
                {
                    finalString.Append($"{convertedPropertyValue}");
                }
            }

            return(finalString.ToString().Trim());
        }