public async Task <IActionResult> Submit(string formId)
        {
            var form = await _contentManager.GetAsync(formId, VersionOptions.Published);

            if (form == null)
            {
                return(NotFound());
            }

            var formPart = form.As <VueForm>();

            // Verify if the form is enabled
            if (!formPart.Enabled.Value)
            {
                return(NotFound());
            }

            // form validation server side script
            var errorsDictionary  = new Dictionary <string, List <string> >();
            var scriptingProvider = new VueFormMethodsProvider(form, errorsDictionary);

            var script = form.As <VueFormScripts>();

            if (!string.IsNullOrEmpty(script?.OnValidation?.Text))
            {
                _scriptingManager.EvaluateJs(script.OnValidation.Text, scriptingProvider);
            }

            if (errorsDictionary.Count > 0)
            {
                return(Json(new { validationError = true, errors = errorsDictionary }));
            }

            if (!string.IsNullOrEmpty(script?.OnSubmitted?.Text))
            {
                _scriptingManager.EvaluateJs(script.OnSubmitted.Text, scriptingProvider);
            }

            // _workflow manager is null if workflow feature is not enabled
            if (_workflowManager != null)
            {
                //todo: make sure this does not create issues if the workflows has a blocking event
                await _workflowManager.TriggerEventAsync(nameof(VueFormSubmittedEvent),
                                                         input : new { VueForm = form },
                                                         correlationId : form.ContentItemId
                                                         );
            }

            // 302 are equivalent to 301 in this case. No permanent redirect
            if (HttpContext.Response.StatusCode == 301 || HttpContext.Response.StatusCode == 302)
            {
                var returnValue = new { redirect = WebUtility.UrlDecode(HttpContext.Response.Headers["Location"]) };
                HttpContext.Response.Clear();
                return(Json(returnValue));
            }
            var formSuccessMessage = await _liquidTemplateManager.RenderAsync(formPart.SuccessMessage?.Text, _htmlEncoder);

            // everything worked fine. send the success signal to the client
            return(Json(new { success = true, successMessage = formSuccessMessage }));
        }
        private object EvaluateScript(string script, VueFormMethodsProvider scriptingProvider, VueForm form, string scriptName)
        {
            object result = null;

            if (!string.IsNullOrWhiteSpace(script))
            {
                try
                {
                    result = _scriptingManager.EvaluateJs(script, scriptingProvider);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"An error occurred evaluating the {scriptName} script");

                    if (form.Debug?.Value == true)
                    {
                        HttpContext.Items.TryAdd($"{Constants.VueFormDebugLog}Script_{scriptName}", ex.ToString());
                    }
                    ModelState.AddModelError("serverErrorMessage", S["A unhandled error occured while executing your request."].ToString());
                }
            }
            return(result);
        }
        public async Task <IActionResult> Submit(string formId)
        {
            var canView = ContentTypePermissionsHelper.CreateDynamicPermission(ContentTypePermissionsHelper.PermissionTemplates[CommonPermissions.ViewContent.Name], "VueForm");

            if (!await _authorizationService.AuthorizeAsync(User, canView))
            {
                return(NotFound());
            }

            var form = await _contentManager.GetAsync(formId, VersionOptions.Published);

            if (form == null)
            {
                return(NotFound());
            }

            var formPart = form.As <VueForm>();

            if (formPart.Disabled.Value)
            {
                return(NotFound());
            }

            if (!_contentPermissionsService.CanAccess(form))
            {
                return(NotFound());
            }

            var scriptingProvider = new VueFormMethodsProvider(form);

            var script = form.As <VueFormScripts>();

            // This object holds the return value of the script
            object serverScriptResult = EvaluateScript(script?.OnValidation?.Text, scriptingProvider, formPart, "OnValidation");

            // Return if any errors are returned in the OnValidation script
            if (ModelState.ErrorCount > 0)
            {
                return(Json(new VueFormSubmitResult(GetErrorDictionary(), serverScriptResult, GetDebugLogs(formPart))));
            }

            serverScriptResult = EvaluateScript(script?.OnSubmitted?.Text, scriptingProvider, formPart, "OnSubmitted");

            // Return if any errors are returned from the OnSubmitted script
            if (ModelState.ErrorCount > 0)
            {
                return(Json(new VueFormSubmitResult(GetErrorDictionary(), serverScriptResult, GetDebugLogs(formPart))));
            }

            // _workflow manager is null if workflow feature is not enabled
            if (_workflowManager != null)
            {
                await _workflowManager.TriggerEventAsync(nameof(VueFormSubmittedEvent),
                                                         input : new { VueForm = form },
                                                         correlationId : form.ContentItemId
                                                         );
            }

            // Return if any errors are returned from the Workflow
            if (ModelState.ErrorCount > 0)
            {
                return(Json(new VueFormSubmitResult(GetErrorDictionary(), serverScriptResult, GetDebugLogs(formPart))));
            }

            // Handle the redirects with ajax requests.
            // 302 are equivalent to 301 in this case. No permanent redirect.
            // This can come from a scripting method or the HttpRedirect Workflow Task
            if (HttpContext.Response.StatusCode == 301 || HttpContext.Response.StatusCode == 302)
            {
                var returnValue = new { redirect = WebUtility.UrlDecode(HttpContext.Response.Headers["Location"]) };
                HttpContext.Response.Clear();
                return(Json(returnValue));
            }

            // This get's set by either the workflow's HttpRedirectTask or HttpResponseTask
            if (HttpContext.Items[WorkflowHttpResult.Instance] != null)
            {
                // Let the HttpResponseTask control the response. This will fail on the client if it's anything other than json
                return(new EmptyResult());
            }

            //try to get the message from the http context as set by the addSuccessMessage() scripting function
            var successMessage = string.Empty;

            if (HttpContext.Items[Constants.VueFormSuccessMessage] != null)
            {
                successMessage = (string)HttpContext.Items[Constants.VueFormSuccessMessage];
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(formPart.SuccessMessage?.Text))
                {
                    var formSuccessMessage = await _liquidTemplateManager.RenderStringAsync(formPart.SuccessMessage.Text, _htmlEncoder);

                    successMessage = await _shortcodeService.ProcessAsync(formSuccessMessage);
                }
            }

            return(Json(new VueFormSubmitResult(successMessage, serverScriptResult, GetDebugLogs(formPart))));
        }