コード例 #1
0
        public IDictionary <string, string> GetValidationAttributes(
            Type modelType,
            string modelPath,
            PropertyInfo property,
            Func <Type, object> services,
            DryvOptions options)
        {
            if (modelPath == null)
            {
                modelPath = string.Empty;
            }

            var rules = from rule in modelType.GetRulesForProperty(property, modelPath)
                        where rule.Rule.IsEnabled(services) &&
                        rule.Rule.EvaluationLocation.HasFlag(RuleEvaluationLocation.Client)
                        select rule;

            var translatedRules = rules.Translate(
                services,
                options,
                modelPath,
                modelType);

            return(this.CreateValidationAttributes(modelType, property, translatedRules));
        }
コード例 #2
0
ファイル: DryvValidator.cs プロジェクト: mhusseini/Dryv
        private void ValidateSingleItem(
            object model,
            object rootModel,
            string path,
            IList <DryvResult> result,
            ICollection <object> processed,
            Func <Type, object> services,
            IDictionary <object, object> cache,
            DryvOptions options)
        {
            if (model == null || processed.Contains(model))
            {
                return;
            }

            processed.Add(model);
            ValidateMethods.GetOrAdd(model.GetType(), this.ruleCompiler.CreateValidateMethods)(
                this,
                model,
                rootModel,
                path,
                result,
                processed,
                services,
                cache,
                options);
        }
コード例 #3
0
ファイル: DryvValidator.cs プロジェクト: mhusseini/Dryv
        internal IEnumerable <DryvResultMessage> ValidateProperty(
            object currentModel,
            object rootModel,
            PropertyInfo property,
            Func <Type, object> services,
            IDictionary <object, object> cache,
            DryvOptions options)
        {
            var disablingRules = this.GetModelsAndRules(currentModel, rootModel, property, services, cache, true, false, RuleType.Disabling);

            if (disablingRules.Any(rule => this.ruleEvaluator.IsDisabled(rule.Value, rule.Key, services)))
            {
                yield break;
            }

            var rules = this.GetModelsAndRules(currentModel, rootModel, property, services, cache, true, false, RuleType.Default);

            foreach (var rule in rules)
            {
                var result = this.ruleEvaluator.Validate(rule.Value, rule.Key, services);
                if (result.IsSuccess())
                {
                    continue;
                }

                yield return(result);

                if (options.BreakOnFirstValidationError)
                {
                    yield break;
                }
            }
        }
コード例 #4
0
        public static IDryvBuilder Configure(IDependencyContainer container, Action <DryvOptions> setupAction = null)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            ModelValidatorProviders.Providers.Add(new DryvModelValidatorProvider());

            var options = new DryvOptions();

            setupAction?.Invoke(options);

            container.RegisterSingleton(typeof(IDryvClientModelValidator), typeof(DryvClientModelValidator));
            container.RegisterSingleton(typeof(ITranslator), typeof(JavaScriptTranslator));
            container.RegisterSingleton(typeof(ITranslatorProvider), typeof(TranslatorProvider));
            container.RegisterInstance(typeof(DryvOptions), options);

            return(new DryvBuilder(container)
                   .AddTranslator <ObjectTranslator>()
                   .AddTranslator <DryvResultTranslator>()
                   .AddTranslator <StringTranslator>()
                   .AddTranslator <EnumerableTranslator>()
                   .AddTranslator <RegexTranslator>());
        }
コード例 #5
0
        public static IDryvMvcBuilder AddDryv(this IMvcBuilder mvcBuilder, Action <DryvOptions> setupAction = null)
        {
            var options = new DryvOptions();

            setupAction?.Invoke(options);

            // As long as mvc validation is not async, we'll
            // run the async validation from an action attribute.
            mvcBuilder.AddMvcOptions(opts => opts.Filters.Add <DryvValidationFilterAttribute>());

            return(RegsterServices(mvcBuilder.Services, options));
        }
コード例 #6
0
ファイル: DryvValidator.cs プロジェクト: mhusseini/Dryv
        internal async Task ValidatePath(
            object input,
            object rootModel,
            PropertyInfo property,
            object parentModel,
            string path,
            IList <DryvResult> result,
            ICollection <object> processed,
            Func <Type, object> services,
            IDictionary <object, object> cache,
            DryvOptions options)
        {
            if (parentModel != null && property != null)
            {
                var disablingRules = this.GetModelsAndRules(parentModel, rootModel, property, services, cache, true, true, RuleType.Disabling);
                var disabled       = await Task.WhenAll(from modelRule in disablingRules
                                                        select this.ruleEvaluator.IsDisabledAsync(modelRule.Value, modelRule.Key, services));

                if (disabled.Any(v => v))
                {
                    return;
                }
            }

            if (input is IEnumerable items)
            {
                string suffix;
                if (path.EndsWith("."))
                {
                    path   = path.TrimEnd('.');
                    suffix = ".";
                }
                else
                {
                    suffix = string.Empty;
                }

                var i = 0;
                foreach (var model in items.OfType <object>())
                {
                    this.ValidateSingleItem(model, rootModel, $"{path}[{i++}]{suffix}", result, processed, services, cache, options);
                }
            }
            else
            {
                this.ValidateSingleItem(input, rootModel, path, result, processed, services, cache, options);
            }
        }
コード例 #7
0
        public static IDryvBuilder AddDryv(this IServiceCollection services, Action <DryvOptions> setupAction)
        {
            var options = new DryvOptions();

            setupAction?.Invoke(options);

            services.TryAddSingleton <IDryvClientModelValidator, DryvClientModelValidator>();
            services.AddSingleton <ITranslator, JavaScriptTranslator>();
            services.AddSingleton <ITranslatorProvider, TranslatorProvider>();
            services.AddSingleton(Options.Create(options));
            services.AddScoped <IModelProvider, ModelProvider>();
            services.AddSingleton <IObjectModelValidator, ObjectModelValidator>(s => new ObjectModelValidator(
                                                                                    s.GetRequiredService <IModelMetadataProvider>(),
                                                                                    s.GetRequiredService <IOptions <MvcOptions> >().Value.ModelValidatorProviders));

            return(new DryvBuilder(services)
                   .AddTranslator <ObjectTranslator>()
                   .AddTranslator <DryvResultTranslator>()
                   .AddTranslator <StringTranslator>()
                   .AddTranslator <EnumerableTranslator>()
                   .AddTranslator <RegexTranslator>());
        }
コード例 #8
0
ファイル: DryvValidator.cs プロジェクト: mhusseini/Dryv
        public async Task <IList <DryvResult> > Validate(object model, DryvOptions options, Func <Type, object> services = null)
        {
            var results = await this.ValidateCore(model, services ?? (t => null), new Dictionary <object, object>(), options);

            return(results.Where(r => r.Message.Any(vr => !vr.IsSuccess())).Take(1).ToList());
        }
コード例 #9
0
ファイル: DryvValidator.cs プロジェクト: mhusseini/Dryv
        private async Task <IEnumerable <DryvResult> > ValidateCore(object model, Func <Type, object> services, IDictionary <object, object> cache, DryvOptions options)
        {
            var result = new List <DryvResult>();

            if (model == null)
            {
                return(result);
            }

            await this.ValidatePath(model, model, null, null, string.Empty, result, new HashSet <object>(), services, cache, options);

            return(result);
        }
コード例 #10
0
        public static IEnumerable <string> Translate(this IEnumerable <DryvRuleNode> rules, Func <Type, object> objectProvider, DryvOptions options, string modelPath, Type modelType)
        {
            var translator = objectProvider(typeof(ITranslator)) as ITranslator;

            return((from r in rules
                    let rule = r.Rule.Translate(translator, options)
                               where rule.TranslationError == null
                               let path = string.IsNullOrWhiteSpace(r.Path) ? r.Path : $".{r.Path}"
                                          let preevaluationOptions = rule.PreevaluationOptionTypes.Select(objectProvider).Union(new[] { path }).ToArray()
                                                                     select rule.TranslatedValidationExpression(preevaluationOptions)).ToList());
        }
コード例 #11
0
        private static DryvRuleDefinition Translate(this DryvRuleDefinition rule, ITranslator translator, DryvOptions options)
        {
            if (rule.TranslatedValidationExpression != null ||
                rule.TranslationError != null)
            {
                return(rule);
            }

            try
            {
                var translatedRule = translator.Translate(rule.ValidationExpression, rule.PropertyExpression);

                rule.TranslatedValidationExpression = translatedRule.Factory;
                rule.PreevaluationOptionTypes       = translatedRule.OptionTypes;
            }
            catch (DryvException ex)
            {
                switch (options.TranslationErrorBehavior)
                {
                case TranslationErrorBehavior.ValidateOnServer:
                    rule.TranslatedValidationExpression = null;
                    rule.PreevaluationOptionTypes       = null;
                    rule.TranslationError = ex;
                    break;

                default:
                    throw;
                }
            }

            return(rule);
        }
コード例 #12
0
 public DryvRuleTranslator(DryvOptions options, Func <Type, object> serviceProvider)
 {
     this.options         = options;
     this.serviceProvider = serviceProvider;
 }
コード例 #13
0
        private static IDryvMvcBuilder RegsterServices(this IServiceCollection services, DryvOptions options)
        {
            services.TryAddSingleton <DryvClientValidationLoader>();
            services.TryAddSingleton <DryvEndpointRouteBuilderProvider>();
            services.TryAddSingleton(typeof(IDryvClientValidationFunctionWriter), options.ClientFunctionWriterType);
            services.TryAddSingleton <ITranslator, JavaScriptTranslator>();
            services.TryAddSingleton <DryvRulesFinder>();
            services.TryAddSingleton <DryvValidator>();
            services.TryAddSingleton <DryvServerRuleEvaluator>();
            services.TryAddSingleton <ITranslatorProvider, TranslatorProvider>();
            services.AddSingleton(Options.Create(options));

            return(new DryvMvcBuilder(services)
                   .AddTranslator <ObjectTranslator>()
                   .AddTranslator <DryvResultTranslator>()
                   .AddTranslator <StringTranslator>()
                   .AddTranslator <EnumerableTranslator>()
                   .AddTranslator <RegexTranslator>()
                   .AddTranslator <CustomCodeTranslator>());
        }