Timon
Timon

Reputation: 1013

Overwrite succesredirect for WFFM on MVC project

I'm trying to overwrite the SuccesRedirect class from the WFFM module. I've found multiple blogs/websites saying how to do this ( like https://adesev.wordpress.com/2014/08/07/wffm-success-redirect/ )

But this doesn't work for me. I'm creating an MVC website, maybe this is the issue ? As there is a Sitecore.forms.config file and a Sitecore.forms.MVC.config file. But I can't seem to find any documentation about this.

Does anyone know how to achieve this or where i can find some more information about this ?

Edit:

I'm using WFFM Version 8.0 rev. 141217.

What i've done is i've followed the blog i've listed above:

Changed Sitecore.forms.config file: Changed the succesAction node with this:

  <successAction>
    <processor type="be.absi.kbs.extensions.SuccesRedirectWFFM, be.absi.kbs.extensions" />
    <processor type="Sitecore.Form.Core.Pipelines.FormSubmit.FormatSuccessMessage, Sitecore.Forms.Core" />
  </successAction>

And i've created a class as follows: ( the assembly name is " be.absi.kbs.extensions " )

namespace be.absi.kbs.extensions
{
    class SuccesRedirectWFFM : ClientPipelineArgs
    {
        public void Process(SubmitSuccessArgs args)
        {

And what I'm trying to do is:

If the url has a returnUrl parameter, it needs to redirect to this url. for example myWebsite/Login?returnUrl=/Blogs Needs to redirect to user to the blog section after a successful login.

But so far i can't reach the Process method.

Upvotes: 2

Views: 795

Answers (1)

Marek Musielak
Marek Musielak

Reputation: 27152

I think you're right and the reason why your code doesn't work is because you're using MVC.

First of all, do not replace the original SuccessRedirect with your SuccesRedirectWFFM action - add you action before the original one:

<successAction>
  <processor type="be.absi.kbs.extensions.SuccesRedirectWFFM, be.absi.kbs.extensions" />
  <processor type="Sitecore.Form.Core.Pipelines.FormSubmit.SuccessRedirect, Sitecore.Forms.Core" />
  <processor type="Sitecore.Form.Core.Pipelines.FormSubmit.FormatSuccessMessage, Sitecore.Forms.Core" />
</successAction>

Then in your code, check the value of returnUrl parameter in both current request url and in url referrer:

public class SuccesRedirectWFFM : ClientPipelineArgs
{
    public void Process(SubmitSuccessArgs args)
    {
        Assert.IsNotNull(args, "args");

        string returnUrl = HttpContext.Current.Request["returnUrl"]

        if (string.IsNullOrEmpty(returnUrl)) 
        {
            returnUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.UrlReferrer.Query)["returnUrl"];
        }

        if (!string.IsNullOrEmpty(returnUrl))
        {
            args.AbortPipeline();
            WebUtil.Redirect(returnUrl, false);
        }
    }
}

The reason for that is in MVC when you submit the form, the request to the server is most probably an ajax call and it does not contain the original url.

Please remember that this is not a final version of the code - it should just point you in the right direction, e.g. you should add additional checks for the type of the Success action.


EDIT: You're right. I've check the code and it looks like in Sitecore MVC all the actions are executed within FormController class. I don't like the solution but it worked for me:

  1. Change the Controller field of the /sitecore/layout/Renderings/Modules/Web Forms for Marketers/Mvc Form item:

    enter image description here

  2. Implement your own controller - if there is no returnurl defined, use default implementation:

namespace My.Assembly.Namespace
{
    public class FormController: SitecoreController, IHasModelFactory, IHasFormDataManager
    {
        public IModelFactory ModelFactory
        {
            get;
            private set;
        }

        public IFormDataManager FormManager
        {
            get;
            private set;
        }

        public FormController() : this((IModelFactory)Sitecore.Configuration.Factory.CreateObject("wffm/modelFactory", true), (IFormDataManager)Sitecore.Configuration.Factory.CreateObject("wffm/formDataManager", true))
        {
        }

        public FormController(IModelFactory modelFactory, IFormDataManager formDataManager)
        {
            Assert.ArgumentNotNull(modelFactory, "modelFactory");
            Assert.ArgumentNotNull(formDataManager, "formDataManager");
            this.ModelFactory = modelFactory;
            this.FormManager = formDataManager;
        }

        [HttpGet]
        public override ActionResult Index()
        {
            return InnerController.Index();
        }

        [SubmittedFormHandler, ValidateHttpAntiForgeryToken, HttpPost]
        public virtual ActionResult Index([ModelBinder(typeof(FormModelBinder))] FormModel form)
        {
            Assert.ArgumentNotNull(form, "form");
            if (this.FormManager == null)
            {
                return null;
            }
            string returnUrl = System.Web.HttpContext.Current.Request["returnUrl"];

            if (string.IsNullOrEmpty(returnUrl))
            {
                returnUrl = HttpUtility.ParseQueryString(System.Web.HttpContext.Current.Request.UrlReferrer.Query)["returnUrl"];
            }

            if (!string.IsNullOrEmpty(returnUrl))
            {
                return base.RedirectToRoute(MvcSettings.SitecoreRouteName, new
                {
                    pathInfo = returnUrl.TrimStart(new char[]
                    {
                        '/'
                    })
                });
            }

            return InnerController.Index(form);
        }

        private Sitecore.Forms.Mvc.Controllers.FormController InnerController
        {
            get
            {
                Sitecore.Forms.Mvc.Controllers.FormController formController =
                    (Sitecore.Forms.Mvc.Controllers.FormController)System.Web.Mvc.ControllerBuilder.Current.GetControllerFactory().CreateController(this.ControllerContext.RequestContext, "Sitecore.Forms.Mvc.Controllers.FormController, Sitecore.Forms.Mvc");
                formController.ControllerContext = this.ControllerContext;
                return formController;
            }
        }
    }
}

Upvotes: 2

Related Questions