Using XForms in EPiServer 8 MVC

Ha, another milestone for me – I was able to create an XForm in EPiServer and hook it up to a block!

First step I took:  Create a Form block, which consists of the following properties:

 public class FormBlock  
{
public virtual string Heading { get; set; }
public virtual XForm Form { get; set; }
[Ignore]
public virtual string ActionUri { get; set; }
}

And then create a controller that populates the ActionUri property. Here is what it looks like:

 public class FormBlockController : BlockController<FormBlock>  
{
private readonly PageRouteHelper pageRouteHelper;
public FormBlockController(PageRouteHelper pageRouteHelper)
{
this.pageRouteHelper = pageRouteHelper;
}
public override ActionResult Index(FormBlock currentBlock)
{
// Create postback url
if (currentBlock.Form != null && this.pageRouteHelper.Page != null)
{
var actionUri = "XFormPost/";
actionUri = UriSupport.AddQueryString(actionUri, "failedAction", "Failed");
actionUri = UriSupport.AddQueryString(actionUri, "successAction", "Success");
currentBlock.ActionUri = actionUri;
}
return PartialView(currentBlock);
}
}

The view is short and simple:

 @model FormBlock  
<h2 @Html.EditAttributes(m => m.Heading)>@Model.Heading</h2>
@using (Html.BeginXForm(Model.Form, new { Action = Model.ActionUri}))
{
Html.RenderXForm(Model.Form);
}

2nd step: Create a Page Type where one of it’s properties is the newly created Form block

 public class FormPage  
{
public virtual FormBlock FormBlock { get; set; }
}

And then create the Controller. Since the ActionUri in the Form block has been set to “XFormPost/”, we create that Action method as you can see below. I have also added Success and Failed actions that need to be further implemented. But for now, we leave it as is.

 public class FormPageController : PageControllerBase<FormPage>  
{
private readonly XFormPageUnknownActionHandler _xformHandler;
private string _contentId;
public FormPageController()
{
_xformHandler = new XFormPageUnknownActionHandler();
_contentId = string.Empty;
}
public ActionResult Index(FormPage currentPage)
{
var model = new PageViewModel<FormPage>(currentPage);
return View(model);
}
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult XFormPost(XFormPostedData xFormpostedData, string contentId)
{
_contentId = contentId;
return _xformHandler.HandleAction(this);
}
#region Success and failed actions
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Success(FormPage currentPage, XFormPostedData xFormPostedData)
{
var model = new PageViewModel<FormPage>(currentPage);
return View("Success", currentPage);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Failed(FormPage currentPage, XFormPostedData xFormPostedData)
{
var model = new PageViewModel<FormPage>(currentPage);
return View("Failed", currentPage);
}
#endregion
}

And finally the View:

 @model PageViewModel<FormPage>  
@{
Layout = "~/Views/Shared/Layouts/_SomeLayout.cshtml";
}
<div class="row">
@Html.PropertyFor(p => p.CurrentPage.FormBlock)
</div>
<div class="row">
@Html.PropertyFor(p => p.CurrentPage.NonTextContent)
</div>

3rd step: Run and create an instance of the Form Page. On the Form block, you can choose which XForm to use in the block.

Or you can also create a new one if needed.

2 Replies to “Using XForms in EPiServer 8 MVC”

  1. If you don't need a controller you can wire it up using a partial. Then you don't need a controller and also can just use the PropertFor with your property. It's how the Alloy Demo is wired and EpiServer suggest using auto wired up parials where possible for performance

Leave a Reply

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