Try our conversational search powered by Generative AI!

Form fields hidden by visitor groups are incorrectly validated

Vote:
 

This is a very specific bug which took me alot of time to find.

We noticed was that some customers were unable to post their forms. They didn't get any error message at all. They just wasn't able to submit. This happen for them when they had previously filled something wrong and had an invalid form. After they corrected their mistake and tried to send it again it didn't work.

More investigations showed that on the 2nd submit the endpoint /EPiServer.Forms/DataSubmit/Submit would say that fields that shouldn't be visible for the user (due to visitor groups) was being validating

The problem was that we had a form actor which in some cases would call CancelSubmit and we had a custom implementation of ActorsExecutingService which removed the form container from cache after submit. We don't know why the form container was removed from cache after submit as it was added in 2018 and the developer has since quit.

To reproduce:

1. Create a form like the image below. Put 2 or more fields in a personalized group and have them all be mandatory. In my example i had visitor groups that matches if the person has visited "About us" or "Search" on the alloy tech demo site.

2. Create a form actor which will call CancelSubmit. For this purpose we'll make this actor only do a cancel and nothing more

public class MyActor : PostSubmissionActorBase, ISyncOrderedSubmissionActor
{
    public override object Run(object input)
    {
        var result = new SubmissionActorResult { CancelSubmit = true, ErrorMessage = "Actor had a problem!" };
        return result;
    }

    public int Order => 1;
}

3. Add a custom implementation to ActorsExecutingService which clears the form container from IContentCacheRemover. 

public class FormsActorsExecutingService : ActorsExecutingService
{
    public override IEnumerable<IPostSubmissionActor> GetFormSubmissionActors(Submission submission,
        FormContainerBlock formContainer, FormIdentity formIden,
        HttpRequest request, HttpResponse response, bool isFormFinalizedSubmission)
    {
        var actors = base.GetFormSubmissionActors(submission, formContainer, formIden, request, response, isFormFinalizedSubmission)?.ToList();

        ServiceLocator.Current.GetInstance<IContentCacheRemover>().Remove(formContainer.Content.ContentLink);
        return actors;
    }
}

4. In ConfigureServices add the new implementation

services.AddSingleton<ActorsExecutingService, FormsActorsExecutingService>();

5. Try posting the form. In this case i first visited "About us" to be included in that visitor group

6. Inspect the response from /EPiServer.Forms/DataSubmit/Submit which looks as we would expect

{
    "isSuccess": false,
    "isProgressiveSubmit": false,
    "redirectUrl": "",
    "message": "Failed to submit.</br>Actor had a problem!",
    "data": null,
    "additionalParams": null
}

7. Try posting the same data again and you'll see that the form itself looks problem free but isn't posting

8. Check the response from /EPiServer.Forms/DataSubmit/Submit again and you'll see this:

{
    "isSuccess": false,
    "isProgressiveSubmit": false,
    "redirectUrl": "",
    "message": null,
    "data": {
        "submissionId": "00000000-0000-0000-0000-000000000000",
        "formLanguage": null,
        "currentStepIndex": 0,
        "isLastestStep": false,
        "validationInfo": [
            {
                "invalidElement": "9655f4a4-df9f-4a0a-9a4c-7c0727db7abe",
                "invalidElementName": "__field_108",
                "invalidElementLabel": "everyoine",
                "validationMessage": "This field is required.",
                "validator": "EPiServer.Forms.Implementation.Validation.RequiredValidator"
            },
            {
                "invalidElement": "df7b99e6-d120-4309-874c-e4cda4435e06",
                "invalidElementName": "__field_109",
                "invalidElementLabel": "search",
                "validationMessage": "This field is required.",
                "validator": "EPiServer.Forms.Implementation.Validation.RequiredValidator"
            }
        ]
    },
    "additionalParams": null
}

Since these fields shouldn't be validated the error makes no sense. I was digging some in the optimizely code using dotPeek as a symbol server and found out that when the form is being validated the code is looking at formContainer.Form.Steps[0].Elements to find the elements it should validate and matches those elements with the incoming form data. On the first post we would get 2 elements in this property and on the second posting we would get 4. So my conclusion is since episerver no longer has the form container in its cache, it will fetch it from the database without taking visitor groups into account which is causing this problem.

For me the solution was to remove the code which evicted the formscontainer form the cache. I would have prefered not to remove it as I'm sure it was added for some reason back in 2018 but i can't figure out what the reason would be. 

Final words: This is of course very specific to this implementation but I feel that the way episerver fetches a content without regards to visitor groups could be a bug that could affect others in other ways than this specifically scenario.

#317143
Feb 14, 2024 12:40
Vote:
 

We're still having this problem even though we corrected what is described in previous post. We can't figure out the pattern for when it happens. Our client is getting alot of complains regarding this from their customers but we haven't been able to find a pattern to when it happens. Sometimes we've been able to see the the incorrect validation but then we try to post again and the problem is gone. 

#320573
Apr 16, 2024 8:36
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.