-
Malformed querystring breaks Sitecore Experience Forms (Value cannot be null. Parameter name: key)
February 5, 2020 Rodrigo Peplau 0
We noticed a bug in Sitecore Experience Forms 9.0.2: when you access a page that has a form passing wrong query string parameters, the system responds with a Runtime Error.
The Error…
For instance, the following url:
==> http://local.myclient.com/myform?good=1&badBecause the query string parameter “bad” does not have a corresponding value, accessing this page will result in a error like this:
Server Error in ‘/’ Application.
Value cannot be null.
Parameter name: keyDescription: An unhandled exception occurred.
Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: keySource Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ArgumentNullException: Value cannot be null. Parameter name: key] System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) +49 System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +14789605 System.Linq.Enumerable.ToDictionary(IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer) +283 Sitecore.ExperienceForms.Mvc.Pipelines.RenderForm.SetFormParameters.Process(RenderFormEventArgs args) +639 (Object , Object ) +14 Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +484 Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) +236 Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) +22 Sitecore.Mvc.Pipelines.PipelineService.RunPipeline(String pipelineName, TArgs args) +195 Sitecore.Mvc.Pipelines.PipelineService.RunPipeline(String pipelineName, TArgs args, Func`2 resultGetter) +161 Sitecore.ExperienceForms.Mvc.Html.HtmlExtensions.BeginRenderRouteForm(HtmlHelper htmlHelper, FormViewModel model, Boolean isPost) +301 ASP._Views_FormBuilder_Form_cshtml.Execute() in D:\Git\ADMI\src\Feature\ADMI.Jobs\Forms\code\obj\CodeGen\Views\FormBuilder\Form.cshtml:6 System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +252 System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +148 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +122 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +375 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +88 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +775 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +775 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +775 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +81 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +701
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.7.3282.0
…The root cause…
Decompiling the “Sitecore.ExperienceForms.Mvc.dll” shows exactly where the issue happens: one of the processors at the <forms.renderForm>, more precisely the “Sitecore.ExperienceForms.Mvc.Pipelines.RenderForm.SetFormParameters” processor, is missing a simple null check.
…And the fix!
Of course, I have tried to extend the original class, to apply my fix in a more “surgical” way. However, due to a private property, we will need to re-implement the whole class.
The fix is very simple and will only require a class and a config patch.
STEP 1 – Create the new SetFormParameters processor
Here is how your processor class should look like. The code is fully commented to show exactly what has been modified and what is simply copied/pasted from the original class.
using System.Collections.Generic; using System.Linq; using System.Web.Routing; using Sitecore.Diagnostics; using Sitecore.ExperienceForms; using Sitecore.ExperienceForms.Mvc.Pipelines.RenderForm; using Sitecore.Mvc.Configuration; using Sitecore.Mvc.Pipelines; namespace MyProject.Pipelines.Forms { /// <summary> /// Pipeline that implements a fix for Sitecore.ExperienceForms.Mvc.Pipelines.RenderForm.SetFormParameters /// The fix is basically a null check in a LINQ expression, but due to a private property /// we are forced to re-implement the whole class in order apply the fix /// </summary> public class SetFormParameters : MvcPipelineProcessor<RenderFormEventArgs> { /// <summary> /// This is the private property that we need to re-implement /// </summary> private readonly IQueryStringProvider _queryStringProvider; /// <summary> /// Constructor is identical to the original class /// </summary> /// <param name="queryStringProvider"></param> public SetFormParameters(IQueryStringProvider queryStringProvider) { Assert.ArgumentNotNull((object) queryStringProvider, nameof (queryStringProvider)); this._queryStringProvider = queryStringProvider; } /// <summary> /// This is where the fix is applied - whole method is identical to original /// except for the LINQ expression in the end of the file /// </summary> /// <param name="args"></param> public override void Process(RenderFormEventArgs args) { Assert.ArgumentNotNull((object) args, nameof (args)); args.FormHtmlId = args.HtmlHelper.AttributeEncode(args.HtmlHelper.ViewData.TemplateInfo.GetFullHtmlFieldId(args.ViewModel.ItemId)); args.Attributes = new Dictionary<string, object>() { { "enctype", (object) "multipart/form-data" },{ "id", (object) args.FormHtmlId },{ "data-sc-fxb", (object) args.ViewModel.ItemId } }; if (!string.IsNullOrEmpty(args.ViewModel.CssClass)) args.Attributes.Add("class", args.ViewModel.CssClass); args.QueryString = new RouteValueDictionary( _queryStringProvider.QueryParameters.AllKeys .Where(p=>p!=null) // <--- The fix itself is here .ToDictionary(key => key, key => (object) _queryStringProvider.QueryParameters[key])); args.RouteName = MvcSettings.SitecoreRouteName; } } }
STEP 2 – Register your processor to make it load instead of the original one
And of course, let’s register the processor using the following config patch:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <forms.renderForm> <processor type="MyProject.Pipelines.Forms.SetFormParameters, MyProject" resolve="true" patch:instead="processor[@type='Sitecore.ExperienceForms.Mvc.Pipelines.RenderForm.SetFormParameters, Sitecore.ExperienceForms.Mvc']"/> </forms.renderForm> </pipelines> </sitecore> </configuration>
Is this officially recognized as a bug?
Yes, it a known bug, registered with the public reference number 324457 (More information about public reference numbers can be found here: https://kb.sitecore.net/articles/853187)
This bug was resolved in Sitecore 9.3, as can be seen in the release notes:
https://dev.sitecore.net/Downloads/Sitecore%20Experience%20Platform/93/Sitecore%20Experience%20Platform%2093%20Initial%20Release/Release%20Notes“If you use a query string that contains parameter without a value to open a page that contains a form, the form is not rendered.”
Categories: Experience Forms, Sitecore 9
Custom rule condition to find Top-N Profile Key (Bug-free) Custom Form IDs in Sitecore Forms
Proudly 9x Sitecore MVP
(2016-2024)
Localization
Recent Posts
Recent Comments
- navan on Meet MVPinny: the AI-Powered Sitecore Assistant
- Adriana on Content generation with Sitecore Connect and ChatGPT
- NAVAN on Automatic Sitecore NuGet upgrades with Powershell
- Hedipo S Menezes on Corey Peplau wrote this - WFFM conflict with Unity DI and a lesson on how Sitecore community is so amazing
- Rodrigo Peplau on ERROR [Content Testing]: Cannot find PhantomJS executable at ' (...) /data/tools/phantomjs/phantomjs.exe'. Aborting screenshot generation.
Archives
- June 2024
- April 2024
- February 2024
- December 2023
- November 2023
- August 2023
- July 2023
- January 2023
- February 2022
- December 2021
- November 2021
- March 2021
- July 2020
- February 2020
- September 2019
- July 2019
- April 2019
- March 2019
- December 2018
- February 2018
- January 2018
- November 2017
- September 2017
- August 2017
- July 2017
- March 2017
- February 2017
- November 2016
- September 2016
- August 2016
- July 2016
- April 2016
- November 2015
- September 2015
- July 2015
- April 2015
- March 2015
- February 2015
Categories
- Actions
- Active Directory
- Analytics
- Architecture
- Bug fixing
- CDP/Personalize
- ChatGPT
- Content Edition Experience
- Content Hub
- Continuous Integration
- Dev
- Development
- Environments
- Experience Editor
- Experience Forms
- Front-end
- Health Check builds
- Helix
- How To
- LDAP
- MVP
- MVP Summit
- MVPinny
- Phantom JS
- Powershell
- QA
- Richtext Editor
- Rules
- Security Provider
- SIF
- Sitecore 9
- Sitecore API
- Sitecore Community
- SItecore Connect
- Sitecore Modules
- Sitecore Rocks
- Sitecore Rule Processor
- Sitecore Symposium
- SPE
- SPEAK
- SUG
- Support Ticket
- TDS
- Team City
- Uncategorized
- Upgrades
- Visual Studio
- WFFM
- Workflow
- XConnect
- xDB
- XM Cloud