Skip to content

Instantly share code, notes, and snippets.

@Rockerby
Last active May 23, 2025 11:02
Show Gist options
  • Save Rockerby/d415e893bf88250585237d9b0b32ea43 to your computer and use it in GitHub Desktop.
Save Rockerby/d415e893bf88250585237d9b0b32ea43 to your computer and use it in GitHub Desktop.
A sample workflow for Umbraco forms that allows the editor to select a custom redirect URL. Great to combine with workflow conditions to give dynamic redirects based on form fields. Created for Umbraco v13, not tested in later versions.
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Umbraco.Forms.Core.Attributes;
using Umbraco.Cms.Core;
using Umbraco.Extensions;
using Microsoft.Extensions.DependencyInjection;
namespace Example.Forms.Workflows
{
public class ConditionalRedirectWorkflow : WorkflowType
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<ConditionalRedirectWorkflow> _logger;
[Setting("Selected Page", Description = "Choose the page within the site to redirect to after submit", View = "Pickers.Content")]
public string SelectedPage { get; set; }
[Setting("Url", Description = "Or enter the URL manually (will override the Selected Page if entered)", View = "TextField")]
public string ManualUrl { get; set; }
public ConditionalRedirectWorkflow(IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider, ILogger<ConditionalRedirectWorkflow> logger)
{
_httpContextAccessor = httpContextAccessor;
_serviceProvider = serviceProvider;
_logger = logger;
this.Id = new Guid("4f88fb22-c8cc-4e41-975c-886859d36a8f");
this.Name = "Conditional Redirect Workflow";
this.Description = "Redirect to a specific destination page, can be used with conditional statements to dynamically redirect users.";
this.Icon = "icon-filter-arrows";
this.Group = "Services";
}
public override Task<WorkflowExecutionStatus> ExecuteAsync(WorkflowExecutionContext context)
{
string redirectUrl = "";
if (!String.IsNullOrWhiteSpace(ManualUrl))
{
redirectUrl = ManualUrl;
}
else if(Int32.TryParse(SelectedPage, out int pageId))
{
try
{
using (var scope = _serviceProvider.CreateScope())
{
IPublishedContentQuery _contentQuery = scope.ServiceProvider.GetService<IPublishedContentQuery>();
var content = _contentQuery.Content(pageId);
if (content != null)
{
redirectUrl = content.Url();
}
}
}
catch(Exception ex)
{
_logger.LogError(ex, "Error fetching content during Conditional Redirect Workflow");
return Task.FromResult(WorkflowExecutionStatus.Failed);
}
}
// If we have a redirect URL then push it into the context to be picked up later in the chain
if (!String.IsNullOrWhiteSpace(redirectUrl))
{
_httpContextAccessor.HttpContext.Items[Umbraco.Forms.Core.Constants.ItemKeys.RedirectAfterFormSubmitUrl] = redirectUrl;
return Task.FromResult(WorkflowExecutionStatus.Completed);
}
else
{
_logger.LogWarning("Unable to redirect workflow with ManualUrl: {0} / Url: {1}", ManualUrl ?? "", SelectedPage ?? "");
return Task.FromResult(WorkflowExecutionStatus.Failed);
}
}
public override List<Exception> ValidateSettings()
{
var ex = new List<Exception>();
if(String.IsNullOrWhiteSpace(ManualUrl) && String.IsNullOrEmpty(SelectedPage))
{
ex.Add(new Exception("You must select at least one; Selected Page or Url"));
}
return ex;
}
}
}
using Ableton.Core.Forms.Workflows;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Forms.Core.Providers;
namespace Example.Forms.Workflows
{
public class FormsComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.WithCollectionBuilder<WorkflowCollectionBuilder>()
.Add<ConditionalRedirectWorkflow>();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment