I've developed a custom workflow to submit form data to a third party system. This submission can either succeed or fail and in the event of a failure it is important to let the user know it has not succeeded. I notice on the workflow's Execute method I can set WorkflowExecutionStatus.Failed in the event that the third party system does not accept the data but there doesn't seem to be any obvious way to handle this failure.
Ideally what I'd like is to either redirect the user back to the form and pop an error message, or even redirect them to a different page than the page specified in the "On Submit" dialog.
I don't know whether or not you have access to the same HttpContext as the posted form from that event.
I do know, however, that you do not have access to the record data from the event.
To subscribe to that event, I usually do it in the Global.asax file:
Thanks for the reply. I wasn't aware of the workflow failed event! I've already got a workaround in place whereby I add some info to the session cache (form id, record id) if it fails, using a special "WorkflowErrored" key and then I've used route hijacking on the success page to check for this value and handle appropriately.
I will check out the workflow failed event for next time though!
For reference to anyone on Forms 7.0, we are just overwriting the e.Form.GoToPageOnSubmit in our workflow to redirect to a 'failed' page (as we still capture the data on error and insert it into a different table).
One caveat is that we have our workflow last in the list and have the workflows running synchronously.
Any idea how to get e.Form.MessageOnSubmit work? I thought I had it working at one point, but I must be crazy because I can't seem to get any message I set on any workflow to override the message set on the default "Submit message / Go to page" workflow.
A tad late but if anyone is still interested, the following works in Forms v7 (not tested in other versions).
Override the OnFormHandled method in UmbracoFormsController and make sure to set MessageOnSubmit in the view model as it is not updated in the standard implementation of UmbracoFormsController
I am having the same issue as above. I am having users submit a Password or challenge phrase field. The password would be stored on the node that hosts the form in clear text. This is not by any means secure I know. When they submit a password that does not match the password on the node I want to send an error back to the client.... again, this is supposed to by a speedbump - not secure in any way...
How would I capture the workflow failed event in Umbraco 8?? I don't think that registering the event on application startup still works in 8 with Composers.... any sample code on that would be greatly appreciated.
AND what is the mechanism within that event that you could inject an error message back to the client? The documentation on this really falls short, seems like any custom workflow operation would need this capability on failure...
While my case above is not directly related to Workflow, it was my initial go-to approach. So I am going to answer my own question out of frustration here in case others are left scratching their heads after reading the Umbraco Forms Extending... section. Examples are incomplete and vague. I'll say it again, if it's an Umbraco Pro product, it's got to be well documented. IMHO this would include approaches to extending forms (so people are not trying to extend incorrectly by making incorrect assumptions about what does what), and a case study sample with complete and downloadable code.
Once you then figure out all the obscure namespaces to include (which are frustratingly never included in the code samples), you should be good to go.
If you are interested. Here's my class to validate a password against a password setting when you create the form and include the custom password type (this is not in any way secure - it's a "vanity" password)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Umbraco.Forms.Core.Providers.FieldTypes;
using Umbraco.Forms.Core.Models;
using Umbraco.Forms.Core.Data.Storage;
namespace WR.Classes
{
public class WRPassword : Password
{
// Added a new setting when we add our field to the form
[Umbraco.Forms.Core.Attributes.Setting("WR Password",
Description = "Please enter a password that you wish to protect the event with.",
View = "Password")]
public string WRPasswordVal { get; set; }
public WRPassword()
{
this.FieldTypeViewName = "FieldType.WRPassword.cshtml";
this.Name = "WR Event Password";
}
public override IEnumerable<string> ValidateField(Form form, Field field, IEnumerable<object> postedValues, HttpContextBase context, IFormStorage formStorage)
{
var baseValidation = base.ValidateField(form, field, postedValues, context, formStorage);
var value = postedValues.FirstOrDefault();
if (value != null && value.ToString().Trim() == WRPasswordVal)
{
return baseValidation;
}
var errors = new List<string>();
errors.AddRange(baseValidation);
errors.Add("Password is incorrect.");
return errors;
}
}
}
In addition to this class, I took the base password field types found in Views\Partials\Forms\Fieldtypes\ and Views\Partials\Forms\Themes\default\FieldTypes\, copied and renamed them to "FieldType.WRPassword.cshtml"
Then finally you would again copy and rename the password field in this folder:App_Plugins\UmbracoForms\Backoffice\Common\FieldTypes\
Once this is done and compliled, you should see your custom field with validation appear as a field type... you can add in a fake password to the custom setting field when you set up that field in Umbraco forms and it will validate against that on submit.
Handling Workflow Failure
I've developed a custom workflow to submit form data to a third party system. This submission can either succeed or fail and in the event of a failure it is important to let the user know it has not succeeded. I notice on the workflow's Execute method I can set WorkflowExecutionStatus.Failed in the event that the third party system does not accept the data but there doesn't seem to be any obvious way to handle this failure.
Ideally what I'd like is to either redirect the user back to the form and pop an error message, or even redirect them to a different page than the page specified in the "On Submit" dialog.
Any ideas?
Hi Mark,
I might have an idea. I haven't tried it myself but it might work for you.
You could try to subscribe to the "WorkflowFailed"-event:
This would fire whenever a workflow has failed.
I don't know whether or not you have access to the same HttpContext as the posted form from that event. I do know, however, that you do not have access to the record data from the event.
To subscribe to that event, I usually do it in the Global.asax file:
Let me know if it works.
Hi Nick,
Thanks for the reply. I wasn't aware of the workflow failed event! I've already got a workaround in place whereby I add some info to the session cache (form id, record id) if it fails, using a special "WorkflowErrored" key and then I've used route hijacking on the success page to check for this value and handle appropriately.
I will check out the workflow failed event for next time though!
Thanks, Mark
Good to hear you found a workaround.
Please let me know if you try the event and if it helped.
For reference to anyone on Forms 7.0, we are just overwriting the e.Form.GoToPageOnSubmit in our workflow to redirect to a 'failed' page (as we still capture the data on error and insert it into a different table).
One caveat is that we have our workflow last in the list and have the workflows running synchronously.
Any idea how to get
e.Form.MessageOnSubmit
work? I thought I had it working at one point, but I must be crazy because I can't seem to get any message I set on any workflow to override the message set on the default "Submit message / Go to page" workflow.Hi Mark,
Running in the same issue as you, did you solved the issue back then?
Also want to send back the messageOnSubmit / or InvalidErrorMessage to the user that submitted the form from workflow.
A tad late but if anyone is still interested, the following works in Forms v7 (not tested in other versions).
Override the
OnFormHandled
method inUmbracoFormsController
and make sure to setMessageOnSubmit
in the view model as it is not updated in the standard implementation ofUmbracoFormsController
Make sure to use this controller in your Form.cshtml or Render.cshtml depending on whether you use a custom theme or not.
I am having the same issue as above. I am having users submit a Password or challenge phrase field. The password would be stored on the node that hosts the form in clear text. This is not by any means secure I know. When they submit a password that does not match the password on the node I want to send an error back to the client.... again, this is supposed to by a speedbump - not secure in any way...
How would I capture the workflow failed event in Umbraco 8?? I don't think that registering the event on application startup still works in 8 with Composers.... any sample code on that would be greatly appreciated.
AND what is the mechanism within that event that you could inject an error message back to the client? The documentation on this really falls short, seems like any custom workflow operation would need this capability on failure...
While my case above is not directly related to Workflow, it was my initial go-to approach. So I am going to answer my own question out of frustration here in case others are left scratching their heads after reading the Umbraco Forms Extending... section. Examples are incomplete and vague. I'll say it again, if it's an Umbraco Pro product, it's got to be well documented. IMHO this would include approaches to extending forms (so people are not trying to extend incorrectly by making incorrect assumptions about what does what), and a case study sample with complete and downloadable code.
In my case, if you are needing to validate data from a form and return any sort of field level validation message, you will have to create your own custom field type. Workflow is not the place for that apparently - even though there is a way to read through the records and validate them - but not return field level messages. The easiest way to do this is to inherit from an existing field type and build on that. Of course (inject sarcasm), you would find the code sample for that on the "Adding a type" page here: https://our.umbraco.com/documentation/Add-ons/umbracoforms/developer/extending/Adding-a-Type and not on the Adding a Field Type page here: https://our.umbraco.com/documentation/Add-ons/umbracoforms/developer/extending/Adding-a-Fieldtype
Take the example from Per at the bottom of the page (https://our.umbraco.com/documentation/Add-ons/umbracoforms/developer/extending/Adding-a-Type) and combine it with the methodology explained here: https://our.umbraco.com/documentation/Add-ons/umbracoforms/developer/extending/Adding-a-Fieldtype
Once you then figure out all the obscure namespaces to include (which are frustratingly never included in the code samples), you should be good to go.
If you are interested. Here's my class to validate a password against a password setting when you create the form and include the custom password type (this is not in any way secure - it's a "vanity" password)
In addition to this class, I took the base password field types found in Views\Partials\Forms\Fieldtypes\ and Views\Partials\Forms\Themes\default\FieldTypes\, copied and renamed them to "FieldType.WRPassword.cshtml"
Then finally you would again copy and rename the password field in this folder:App_Plugins\UmbracoForms\Backoffice\Common\FieldTypes\
Once this is done and compliled, you should see your custom field with validation appear as a field type... you can add in a fake password to the custom setting field when you set up that field in Umbraco forms and it will validate against that on submit.
Hope this helps!
Cheers,
Jamie
is working on a reply...