Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • James Jackson-South 489 posts 1747 karma points c-trib
    Sep 12, 2016 @ 07:21
    James Jackson-South
    0

    Redirect to custom "Thank you" page based on answers.

    Umbraco Forms 4.3.2

    I'm trying to add a custom workflow that redirects to a custom page based on submitted answers but I have hit a wall.

    When implementing a custom workflow from the WorkflowType base class the appropriate method to override is

    public override WorkflowExecutionStatus Execute(Record record, RecordEventArgs e)
    

    As you can see the return type is WorkflowExecutionStatus however if I want to use Response.Redirect(url) then I cannot possibly return a result since that method aborts the current thread throwing a ThreadAbortException.

    Theoretically I could maybe use Response.RedirectToRoute() but I have no idea how I would find the route to the picked "Thank you" page.

    I cannot find any documentation on how to do this and there doesn't seem to be an implementation in the source (Yes I know, bad James, but make the docs better.) despite there being a redirect workflow available in the back office.

    Any ideas how I would implement this?

    Additionally I will add, adding a macro or custom code to the "Thank you" page is definitely a no-no since that would be an enormous hack which you should be ashamed of for thinking up.

    Cheers

    James

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Sep 12, 2016 @ 07:29
    Lars-Erik Aabech
    1

    You should rather implement a doctype that varies. Point to it as the "thank you" page. In it, have ie. some nested content with a predicate and a new URL or some content.

    In a RenderMvcController, template or child-controller, access TempData["RecordId"] to get the posted record id, and check your predicates against it.

    Makes sense?

    Here's a snippet I use in the response view for some fancy Forms logic. You could change it from returning stuff to doing the redirect. Or make it return the content you want to show.

        public static List<ScoreResult> Fetch(ViewContext context)
        {
            if (context == null || context.TempData == null)
                throw new Exception("Invalid controller context or session state");
    
            Guid recordId = Guid.Empty;
            if (context.TempData.ContainsKey("Forms_Current_Record_id"))
                recordId = (Guid)context.TempData["Forms_Current_Record_id"];
    
            var record = context.ViewData["Record"] as Record;
    
            if (recordId == Guid.Empty && record != null)
            {
                recordId = record.UniqueId;
            }
    
            // TODO: Refactor everything and abstract cache
            var resultCacheKey = "Result_" + recordId;
            if (HttpContext.Current != null && HttpContext.Current.Items.Contains(resultCacheKey))
            {
                return (List<ScoreResult>) HttpContext.Current.Items[resultCacheKey];
            }
    
            if (record == null && recordId != Guid.Empty)
            { 
                var recordStorage = new RecordStorage(ApplicationContext.Current.DatabaseContext);
                record = recordStorage.GetRecordByUniqueId(recordId);
            }
    
            if (record == null)
                return new List<ScoreResult>();
    
            Dictionary<Guid, string> recordData;
            if (record.RecordData != null)
                recordData = JsonConvert.DeserializeObject<Dictionary<Guid, string>>(record.RecordData);
            else
                recordData = record.RecordFields.ToDictionary(f => f.Key, f => f.Value.ValuesAsString());
    
            var form = record.GetForm();
    
            var workflowStorage = new WorkflowStorage();
            var activeWorkFlows = workflowStorage.GetActiveWorkFlows(form, FormState.Submitted);
            var settings = activeWorkFlows
                .Where(wf => wf.Type is IWeightedResultsWorkflow)
                .Where(wf => wf.Settings.ContainsKey("ResultField"))
                .Select(wf => wf.Settings["ResultField"]);
    
            var results = new List<ScoreResult>();
    
            foreach (var key in settings)
            {
                Guid fieldId;
                if (!Guid.TryParse(key, out fieldId))
                    continue;
                if (!recordData.ContainsKey(fieldId))
                    continue;
                var resultValue = recordData[fieldId];
                var result = JsonConvert.DeserializeObject<ScoreResult>(context.HttpContext.Server.UrlDecode(resultValue ?? ""), SerializationOptions.Options);
                if (result != null)
                {
                    results.Add(result);
                }
            }
    
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items.Add(resultCacheKey, results);
            }
    
            return results;
        }
    
  • James Jackson-South 489 posts 1747 karma points c-trib
    Sep 12, 2016 @ 07:52
    James Jackson-South
    0

    Hi Lars,

    Thanks for the code sample and workflow process. I'll probably end up doing something similar

    I feel like this should be possible within Workflow though. It's the correct place for it and how does the original exists if it isn't?

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Sep 12, 2016 @ 07:55
    Lars-Erik Aabech
    0

    If the editors / customers have access to forms and workflows, there's no way you can guarantee they add the "thank-you" workflow last. If they don't, it'll redirect before all workflows have executed. You also have the option of running workflows asynchronously, and then the Response.Redirect would probably throw.

    If you don't mind the above, you could probably go like so in the workflow:

    Response.Clear();
    Response.Redirect("some/url");
    Response.End();
    
  • Magic Mike 3 posts 73 karma points
    Sep 30, 2020 @ 11:43
    Magic Mike
    0

    Just for anyone coming across this I don't think you can run Workflows asynchronously in Umbraco Forms 8

Please Sign in or register to post replies

Write your reply to:

Draft