HappyPorch / uSplit

A/B Testing plugin for Umbraco
The Unlicense
11 stars 7 forks source link

"Filtering is not allowed." - Support templates that render child actions. #4

Open t1er opened 8 years ago

t1er commented 8 years ago

Trying to use usplit with Umbraco Contour 3.0.28

When load original page it show empty form container

error log:

2016-08-23 14:19:46,057 [P17620/D2/T43] ERROR ASP._Page_macroScripts_MvcRenderContourForm_cshtml - MvcRenderContourForm System.Web.HttpException (0x80004005): Filtering is not allowed. at System.Web.HttpResponse.set_Filter(Stream value) at Endzone.uSplit.Pipeline.VariationReportingFilterAttribute.OnActionExecuted(ActionExecutedContext filterContext) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) at Umbraco.Forms.Mvc.Bridge.Html.MvcBridgeExtensions.RenderMvcAction(HtmlHelper helper, String action, String controller, String formId, String antiForgeryToken, Object node, Object parameter) at ASP._Page_macroScripts_MvcRenderContourForm_cshtml.Execute() in d:\home\site\wwwroot\macroScripts\MvcRenderContourForm.cshtml:line 15

ondrejpialek commented 8 years ago

Hi @t1er,

thanks a lot for reporting this issue. The error you are seeing is coming from a limitation of uSplit - it does not work on pages that render child actions. In your particular case it is the call to RenderMvcAction.

The reason it fails is because uSplit (the VariationReportingFilterAttribute filter) modifies the output of your page as it is sent to your visitors and injects a piece of JavaScript to your page if it is needed (when you have an experiment running for that page). This does not work when a child actions are involved unfortunately (a limitation of ASP.NET).

To support this scenario we will have to add a new helper method for you to add to your master template. This helper will render the JS fragment if necessary, and suppress the global filter.

Thanks, Ondrej.

ondrejpialek commented 8 years ago

Hi @t1er,

Latest version of uSplit allows you to call @Html.RenderAbTestingScriptTags() in your master layout (should go just after the opening <head>). If this method gets called, no filtering will get used and no exception will be thrown. Theoretically anyway... let me know if that worked for you or not ;)

Thanks, Ondrej.

t1er commented 8 years ago

@ondrejpialek I've updated usplit to latest, but I receive new error.

My flow is:

Page1 with form. When fill form and click submit form redirect to step 2 page which i'd like to a/b test.

but after inserting @Html.RenderAbTestingScriptTags() on step2 I have:

Cannot perform runtime binding on a null reference

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform runtime binding on a null reference

Source 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:

[RuntimeBinderException: Cannot perform runtime binding on a null reference] CallSite.Target(Closure , CallSite , Object ) +153 Umbraco.Forms.Mvc.Controllers.FormRenderController.ContourForm(FormViewModel model, Boolean captchaIsValid) +6057 lambda_method(Closure , ControllerBase , Object[] ) +195 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +229 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +35 System.Web.Mvc.Async.AsyncControllerActionInvoker.b39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39 System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +71 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.AsyncInvocationWithFilters.b3d() +72 System.Web.Mvc.Async.<>cDisplayClass46.b3f() +386 System.Web.Mvc.Async.<>cDisplayClass46.b3f() +386 System.Web.Mvc.Async.<>cDisplayClass46.b3f() +386 System.Web.Mvc.Async.<>cDisplayClass46.b3f() +386 System.Web.Mvc.Async.<>cDisplayClass46.b3f() +386 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.<>cDisplayClass2b.b1c() +38 System.Web.Mvc.Async.<>cDisplayClass21.b1e(IAsyncResult asyncResult) +186 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38 System.Web.Mvc.Controller.b1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +67 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38 System.Web.Mvc.MvcHandler.b5(IAsyncResult asyncResult, ProcessRequestState innerState) +44 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

and browser url is /umbraco/backoffice/usplit/FormRender/ContourForm

ondrejpialek commented 8 years ago

Hi @t1er,

thanks a lot for taking time to test the new version. I reproduced the same error with some fake context mockery, but seems like fixing that scenario did not help in your case. I will have to install Contour on a test site and reproduce it properly that way.

I have a few questions:

  1. Could you please let me know what Umbraco version you are using, and what version of Contour you are using?
  2. Then I am assuming you are just rendering a form from a RTE using a macro, am I right?
  3. How exactly do you do (or set up) the redirect?
  4. What is on the second page? Another form or is it just a thank you page with some text?
  5. If you are testing just the Thank you page, do you only have an experiment set up for that page - page 2, or do you have an experiment set up for page 1 - the page with the form?

Thanks, Ondrej!

t1er commented 8 years ago

Hi @ondrejpialek ,

  1. Umbraco latest 7.5.2 and Contour 3.0.28
  2. Correct. Rendering via RTE.
  3. I have the first page with Contour form which redirects to (Send to page (Contour content picker)) second step. The second step is a page with another contour form (not step 2). The second page is under test with uSplit. Variation for this page (step 2b) exists in the same place as step 2. Variation page contains third Contour form. So I'd like to show the second step with different page content (different forms).

Thanks, Mike

t1er commented 8 years ago

@ondrejpialek any news?

ondrejpialek commented 8 years ago

Hi @t1er, I am definitely planning to fix this issue, as we want uSplit to support as many scenarios as possible.

This issue is somewhat peculiar in that in involves 3rd party plugins, and reproducing the problem will take a non-trivial amount of time. We are unfortunately in the middle of an important project right now and cannot spend time on this. I am expecting to give this a go early October after we go live.

Feel free to investigate the problem yourself if you want, we encourage people to submit pull requests. If this is a critical issue we also provide commercial support for uSplit (I am planning to fix this one for free though if you wait enough, just saying) ;)