Пример #1
0
        public async Task Only_call_EvaluateCode_method_once()
        {
            CustomMethods.Counter = 0;
            var context = new ScriptContext {
                ScriptMethods = { new CustomMethods() },
            }.Init();

            var fn  = ScriptCodeUtils.EnsureReturn("chooseColor(`#336699`)");
            var ret = await context.EvaluateCodeAsync(fn);

            Assert.That(ret, Is.EqualTo("#336699"));
            Assert.That(CustomMethods.Counter, Is.EqualTo(1));

            CustomMethods.Counter = 0;
            fn  = ScriptCodeUtils.EnsureReturn("chooseColor");
            ret = await context.EvaluateCodeAsync(fn);

            Assert.That(ret, Is.EqualTo("#ffffff"));
            Assert.That(CustomMethods.Counter, Is.EqualTo(1));

            CustomMethods.Counter = 0;
            fn  = ScriptCodeUtils.EnsureReturn("chooseColor()");
            ret = await context.EvaluateCodeAsync(fn);

            Assert.That(ret, Is.EqualTo("#ffffff"));
            Assert.That(CustomMethods.Counter, Is.EqualTo(1));
        }
Пример #2
0
        public static void AddTypeValidator(List <ITypeValidator> to, IValidateRule attr)
        {
            var appHost = HostContext.AppHost;

            if (!string.IsNullOrEmpty(attr.Condition))
            {
                var evalCode = ScriptCodeUtils.EnsureReturn(attr.Condition);
                var code     = appHost.ScriptContext.CodeSharpPage(evalCode);
                to.Add(new ScriptValidator(code, attr.Condition).Init(attr));
            }
            else if (!string.IsNullOrEmpty(attr.Validator))
            {
                var ret = appHost.EvalExpression(attr
                                                 .Validator); //Validators can't be cached due to custom code/msgs
                if (ret == null)
                {
                    ThrowNoValidator(attr.Validator);
                }

                if (ret is ITypeValidator validator)
                {
                    to.Add(validator.Init(attr));
                }
                else if (ret is List <object> objs)
                {
                    foreach (var o in objs)
                    {
                        if (o is ITypeValidator itemValidator)
                        {
                            to.Add(itemValidator.Init(attr));
                        }
                        else
                        {
                            ThrowInvalidValidator(attr.Validator, nameof(ITypeValidator));
                        }
                    }
                }
                else
                {
                    ThrowInvalidValidator(attr.Validator, nameof(ITypeValidator));
                }
            }
            else
            {
                ThrowInvalidValidateRequest();
            }
        }
        public async Task Any(EvalScript request)
        {
            var feature = HostContext.AssertPlugin <DesktopFeature>();

            RequestUtils.AssertAccessRole(base.Request, accessRole: feature.AccessRole, authSecret: request.AuthSecret);

            var    appHost = HostContext.AppHost;
            string script;
            var    method = ((script = request.EvaluateScript) != null
                 ? nameof(request.EvaluateScript)
                 : (script = request.EvaluateCode) != null
                     ? nameof(request.EvaluateCode)
                     : (script = request.EvaluateLisp) != null
                         ? nameof(request.EvaluateLisp)
                         : (script = request.RenderScript) != null
                             ? nameof(request.RenderScript)
                             : (script = request.RenderCode) != null
                                 ? nameof(request.RenderCode)
                                 : (script = request.RenderLisp) != null
                                     ? nameof(request.RenderLisp)
                                     : null) ??
                            ((script = request.EvaluateScriptAsync) != null
                 ? nameof(request.EvaluateScriptAsync)
                 : (script = request.EvaluateCodeAsync) != null
                     ? nameof(request.EvaluateCodeAsync)
                     : (script = request.EvaluateLispAsync) != null
                         ? nameof(request.EvaluateLispAsync)
                         : (script = request.RenderScriptAsync) != null
                             ? nameof(request.RenderScriptAsync)
                             : (script = request.RenderCodeAsync) != null
                                 ? nameof(request.RenderCodeAsync)
                                 : (script = request.RenderLispAsync) != null
                                     ? nameof(request.RenderLispAsync)
                                     : null)
                            ?? throw new ArgumentNullException(nameof(request.EvaluateCode));

            async Task HandleExceptionAsync(Exception e)
            {
                log.Error(e.Message, e);
                base.Response.StatusCode        = 500;
                base.Response.StatusDescription = e.GetType().Name;
                base.Response.ContentType       = MimeTypes.PlainText;
                await base.Response.OutputStream.WriteAsync(MemoryProvider.Instance.ToUtf8(e.ToString().AsSpan()));

                await base.Response.EndRequestAsync(skipHeaders : true);
            }

            async Task SetResult(object value, string resultType = " result")
            {
                base.Response.ContentType       = MimeTypes.Json;
                base.Response.StatusCode        = 200;
                base.Response.StatusDescription = method + resultType;
                await base.Response.EndRequestAsync(skipHeaders : false, async res => {
                    using var ms = MemoryStreamFactory.GetStream();
                    JsonSerializer.SerializeToStream(value, ms);
                    ms.Position = 0;
                    await ms.CopyToAsync(base.Response.OutputStream);
                });
            }

            async Task SetOutput(PageResult result)
            {
                base.Response.StatusCode        = 200;
                base.Response.StatusDescription = method + " result";
                base.Response.ContentType       = MimeTypes.PlainText;
                await base.Response.EndRequestAsync(skipHeaders : false, async res => {
                    using var ms = MemoryStreamFactory.GetStream();
                    await result.RenderToStreamAsync(ms);
                    ms.Position = 0;
                    await ms.CopyToAsync(res.OutputStream);
                });
            }

            var args = new Dictionary <string, object> {
                [ScriptConstants.Request] = base.Request,
            };

            if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.EvaluateScript)))
            {
                await SetResult(await appHost.ScriptContext.EvaluateAsync(script, args));
            }
            else if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.RenderScript)))
            {
                await SetOutput(new PageResult(appHost.ScriptContext.SharpScriptPage(script)).AssignArgs(args));
            }

            else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.EvaluateCode)))
            {
                await SetResult(await appHost.ScriptContext.EvaluateCodeAsync(ScriptCodeUtils.EnsureReturn(script), args));
            }
            else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.RenderCode)))
            {
                await SetOutput(new PageResult(appHost.ScriptContext.CodeSharpPage(script)).AssignArgs(args));
            }

            else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.EvaluateLisp)))
            {
                await SetResult(await appHost.ScriptContext.EvaluateLispAsync(ScriptLispUtils.EnsureReturn(script), args));
            }
            else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.RenderLisp)))
            {
                await SetOutput(new PageResult(appHost.ScriptContext.LispSharpPage(script)).AssignArgs(args));
            }

            if (base.Response.IsClosed)
            {
                return;
            }

            async Task setResultAsync(Task <object> valueTask, string resultType = " result")
            {
                try
                {
                    base.Response.ContentType       = MimeTypes.Json;
                    base.Response.StatusCode        = 200;
                    base.Response.StatusDescription = method + resultType;
                    await base.Response.EndRequestAsync(skipHeaders : false, async res => {
                        using var ms = MemoryStreamFactory.GetStream();
                        JsonSerializer.SerializeToStream(await valueTask, ms);
                        await ms.CopyToAsync(base.Response.OutputStream);
                    });
                }
                catch (Exception e)
                {
                    await HandleExceptionAsync(e);
                }
            }

            async Task setOutputAsync(PageResult result)
            {
                try
                {
                    base.Response.StatusCode        = 200;
                    base.Response.StatusDescription = method + " async result";
                    base.Response.ContentType       = MimeTypes.PlainText;
                    await base.Response.EndRequestAsync(skipHeaders : false, async res => {
                        using var ms = MemoryStreamFactory.GetStream();
                        await result.RenderToStreamAsync(ms);
                        await ms.CopyToAsync(res.OutputStream);
                    });
                }
                catch (Exception e)
                {
                    await HandleExceptionAsync(e);
                }
            }

            if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.EvaluateScriptAsync)))
            {
                await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateAsync(script, args), " async result"));
            }
            else if (method.EqualsIgnoreCase(nameof(ScriptTemplateUtils.RenderScriptAsync)))
            {
                await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.SharpScriptPage(script)).AssignArgs(args)));
            }

            else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.EvaluateCodeAsync)))
            {
                await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateCodeAsync(ScriptCodeUtils.EnsureReturn(script), args), " async result"));
            }
            else if (method.EqualsIgnoreCase(nameof(ScriptCodeUtils.RenderCodeAsync)))
            {
                await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.CodeSharpPage(script)).AssignArgs(args)));
            }

            else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.EvaluateLispAsync)))
            {
                await Task.Run(async() => await setResultAsync(appHost.ScriptContext.EvaluateLispAsync(ScriptLispUtils.EnsureReturn(script), args), " async result"));
            }
            else if (method.EqualsIgnoreCase(nameof(ScriptLispUtils.RenderLispAsync)))
            {
                await Task.Run(async() => await setOutputAsync(new PageResult(appHost.ScriptContext.LispSharpPage(script)).AssignArgs(args)));
            }
            else
            {
                throw new NotSupportedException($"Unsupported script API '{method}', supported: " +
                                                "EvaluateScript/Async, EvaluateCode/Async, EvaluateLisp/Async");
            }
        }
Пример #4
0
        public static void AddRule(this List <IPropertyValidator> validators, PropertyInfo pi, IValidateRule propRule)
        {
            var appHost = HostContext.AppHost;

            foreach (var ruleFilter in RuleFilters)
            {
                ruleFilter(pi, propRule);
            }

            IPropertyValidator apply(IPropertyValidator validator)
            {
                var errorCode = propRule.ErrorCode;

                if (!string.IsNullOrEmpty(errorCode))
                {
                    validator.Options.ErrorCodeSource = new StaticStringSource(errorCode);
                }
                else
                {
                    if (propRule.Condition != null &&
                        ConditionErrorCodes.TryGetValue(propRule.Condition, out errorCode))
                    {
                        validator.Options.ErrorCodeSource = new StaticStringSource(errorCode);
                    }
                }

                if (!string.IsNullOrEmpty(propRule.Message))
                {
                    validator.Options.ErrorMessageSource = new StaticStringSource(propRule.Message.Localize());
                }
                else if (errorCode != null && ErrorCodeMessages.TryGetValue(errorCode, out var errorMsg))
                {
                    validator.Options.ErrorMessageSource = new StaticStringSource(errorMsg.Localize());
                }

                return(validator);
            }

            if (propRule.Validator != null)
            {
                var ret = appHost.EvalExpression(propRule
                                                 .Validator); //Validators can't be cached due to custom code/msgs
                if (ret == null)
                {
                    ThrowNoValidator(propRule.Validator);
                }

                if (ret is IPropertyValidator validator)
                {
                    validators.Add(apply(validator));
                }
                else if (ret is List <object> objs)
                {
                    foreach (var o in objs)
                    {
                        if (o is IPropertyValidator itemValidator)
                        {
                            validators.Add(apply(itemValidator));
                        }
                        else
                        {
                            ThrowInvalidValidator(propRule.Validator, nameof(IPropertyValidator));
                        }
                    }
                }
                else
                {
                    ThrowInvalidValidator(propRule.Validator, nameof(IPropertyValidator));
                }
            }
            else if (!string.IsNullOrEmpty(propRule.Condition))
            {
                var evalCode = ScriptCodeUtils.EnsureReturn(propRule.Condition);
                var page     = appHost.ScriptContext.CodeSharpPage(evalCode);
                validators.Add(apply(new ScriptConditionValidator(page)));
            }
            else
            {
                ThrowInvalidValidate();
            }
        }
Пример #5
0
        public static SharpPage ParseCondition(ScriptContext context, string condition)
        {
            var evalCode = ScriptCodeUtils.EnsureReturn(condition);

            return(context.CodeSharpPage(evalCode));
        }
Пример #6
0
        public static void AddRule(this List <IPropertyValidator> validators, PropertyInfo pi, IValidateRule propRule)
        {
            var appHost = HostContext.AppHost;

            foreach (var ruleFilter in RuleFilters)
            {
                ruleFilter(pi, propRule);
            }

            IPropertyValidator apply(IPropertyValidator validator)
            {
                var errorCode = propRule.ErrorCode;

                if (!string.IsNullOrEmpty(errorCode))
                {
                    validator.Options.ErrorCodeSource = new StaticStringSource(errorCode);
                }
                else
                {
                    if (propRule.Condition != null &&
                        ConditionErrorCodes.TryGetValue(propRule.Condition, out errorCode))
                    {
                        validator.Options.ErrorCodeSource = new StaticStringSource(errorCode);
                    }
                }

                if (!string.IsNullOrEmpty(propRule.Message))
                {
                    validator.Options.ErrorMessageSource =
                        new StaticStringSource(appHost.ResolveLocalizedString(propRule.Message));
                }
                else if (errorCode != null && ErrorCodeMessages.TryGetValue(errorCode, out var errorMsg))
                {
                    validator.Options.ErrorMessageSource =
                        new StaticStringSource(appHost.ResolveLocalizedString(errorMsg));
                }

                return(validator);
            }

            if (propRule.Validator != null)
            {
                var ret = appHost.EvalExpression(propRule
                                                 .Validator); //Validators can't be cached due to custom code/msgs
                if (ret == null)
                {
                    throw new NotSupportedException(
                              $"Could not resolve matching '{propRule.Validator}` Validator Script Method. " +
                              $"Ensure it's registered in AppHost.ScriptContext and called with correct number of arguments.");
                }

                if (ret is IPropertyValidator validator)
                {
                    validators.Add(apply(validator));
                }
                else if (ret is List <object> objs)
                {
                    foreach (var o in objs)
                    {
                        if (o is IPropertyValidator itemValidator)
                        {
                            validators.Add(apply(itemValidator));
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException($"{propRule.Validator} is not an IPropertyValidator");
                }
            }
            else if (!string.IsNullOrEmpty(propRule.Condition))
            {
                var evalCode = ScriptCodeUtils.EnsureReturn(propRule.Condition);
                var page     = appHost.ScriptContext.CodeSharpPage(evalCode);
                validators.Add(apply(new ScriptConditionValidator(page)));
            }
        }