WFFM - Sitecore Context Item NULL inside a Save Action

Business requirements

There is a use case in one of our clients at Nish Tech, where a WFFM form, with a Submit E-mail Save Action, is supposed to be reused at several different parts of the website. It should have the same fields and look & feel at every place we want to reuse it, the only difference would be that the e-mail would be submitted to different addresses depending on what page the form is located.

The pages where this form will be allowed are what we call “Communities”. Each of them has a couple of fields with e-mails (Eg: Sales E-mail, Human Resources E-mail) from which we wanted to have WFFM looking for, instead of using the one hardcoded at the WFFM itself.

One may ask: why not duplicate the WFFM form and hardcode a different e-mail for each page we need? The answer is plenty clear: we will have more than 80 communities, and growing. That would mean more than 80 duplications of the WFFM form, which sound quite abusive. If we happen to need some kind of maintenance at these forms, this would be a nightmare.

The resulting implementation will be subject of a future blog post, this one in particular will focus in a specific challenge: how to access the Sitecore.Context.Item inside a WFFM Save Action.

Technical challenge

So the idea is that WFFM should look into a field at the item where it is located, grabbing the destiny e-mail from there instead of the hardcoded e-mail at the WFFM Form itself. To achieve this we will need to access the current context item (Sitecore.Context.Item), which surprisingly is not available inside a Save Action, as confirmed by Sitecore in a Helpdesk ticket we created.

To be fair, Sitecore.Context.Item is available in Preview Mode because Sitecore explicitly sets the current item ID at the querystring. However, in publish mode there are no such parameter at the querystring, which happens to let Sitecore.Context.Item with value NULL when you are inside a Save Action. This happens because the Item Resolver only runs AFTER the Save Action, thus Context.Item will only be filled after the Save Action is executed.

Implementing a Solution

So here is the solution we ended up arranging, with best possible reusing of same WFFM and not jeopardizing WFFM’s or Sitecore’s normal pipelines and flows.

Step 1 – Create a new WFFM field for Sitecore.Context.Item

This would be a hidden field at the form, responsible for carry on the Sitecore.Context.Item.ID, available at the time when the form is rendering, to the Save Action where that is not available.

  1. At /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Simple Types start by duplicating the “Single-Line Text” field to serve as a basis for our new field;
  2. Rename it to “Sitecore Context Item ID”;
  3. Fill the field “MVC Type” with the assembly we are going to create to our new field:
    ClientName.Website.Core.WFFM.Fields.SitecoreContextItemId, ClientName.Website.Core
  4. Create a view called “SitecoreContextItemId.cshtml” for this field under /Views/Form/EditorTemplates and add the following content. Notice the <span style=”display:none;”> surrounding the field, which will make it hidden when the form renders
@using Sitecore.Forms.Mvc.Html
@model Sitecore.Forms.Mvc.ViewModels.FieldViewModel
<span style="display:none;">
@using (Html.BeginField())


Step 2 – Make that field comes auto-populated with Context.Item

This class, which is tied to the field at the bullet 3 of Step 1, implements the logic that makes the field renders with Sitecore.Context.Item.ID auto-populated. Notice that this is simply inheriting from SingleLineTextField, adding the ID to the field Value, and nothing else.

using Sitecore.Forms.Mvc.ViewModels.Fields;
namespace ClientName.Website.Core.WFFM.Fields
    public class SitecoreContextItemId : SingleLineTextField
        public override void Initialize()
            if (this.MaxLength != 0)
            this.MaxLength = 256;
            this.Value = Sitecore.Context.Item.ID.ToString();

Step 3 – Make Context.Item be automatically filled from that field

We could very well now just go ahead and read from that field, couldn’t we? But to make things pretty, instead of that we are going to implement a pipeline processor to populate Sitecore.Context.Item.

  • Create an include file “Sitecore.WFFM.SetContextItem.config” with following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="">
        <processor type="ClientName.Website.Core.WFFM.Pipelines.SetContextItem,ClientName.Website.Core" patch:after="processor[@type='Sitecore.Forms.Mvc.Pipelines.Submit.RegisterFormSubmitEvent,Sitecore.Forms.Mvc']"/>
  • Then let’s implement this class to make Sitecore.Context.Item be populated.
using System.Linq;
using Sitecore.Data;
using Sitecore.Diagnostics;
using Sitecore.Forms.Mvc.Interfaces;
using Sitecore.Forms.Mvc.Models;
using Sitecore.Forms.Mvc.Pipelines;
namespace ClientName.Website.Core.WFFM.Pipelines
    public class SetContextItem : FormProcessorBase<IFormModel>
        public override void Process(FormProcessorArgs<IFormModel> args)
            Assert.ArgumentNotNull((object)args, "args");
            var model = args.Model as FormModel;
            if (model == null || Sitecore.Context.Item!=null)
            var contextField = model.Item.Fields.FirstOrDefault(p => p.MVCClass.Contains(typeof(Fields.SitecoreContextItemId).FullName));
            if (contextField == null)
            var contextFieldResult = model.Results.FirstOrDefault(p => p.FieldName == contextField.Name);
            if (contextFieldResult == null)
            var contextItem = Sitecore.Context.Database.GetItem(new ID(contextFieldResult.Value.ToString()));
            Sitecore.Context.Item = contextItem;

Pay special attention to the following lines:

var contextField = model.Item.Fields.FirstOrDefault(p => p.MVCClass.Contains(typeof(Fields.SitecoreContextItemId).FullName));

Where the assembly name we created at Step 2 is used to find our field and next:

var contextFieldResult = model.Results.FirstOrDefault(p => p.FieldName == contextField.Name);

 Where the ID value is taken to later populate Sitecore.Context.Item:

var contextItem = Sitecore.Context.Database.GetItem(new ID(contextFieldResult.Value.ToString()));
Sitecore.Context.Item = contextItem;


Step 4 – Add the field to your WFFM Form

Easy part, but if forgotten nothing will work. Make sure your new field is present at your WFFM Form:

WFFM Field Sitecore Context Item

Posted in WFFM

Leave a Reply

Your email address will not be published. Required fields are marked *


  Am Not Spammer

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>