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.

EPiServer: Create a Gallery / ImageSlider Block

One of the tasks I needed to do was to create a block that takes in a list of Images and displays these in an ImageSlider, with the help of almighty Javascript. This might not be the best solution for it, but hey it works.

First of all, I created a Block Type and gave it one property

 public class ImageSliderBlock : BlockData  
{
public virtual LinkItemCollection Images { get; set; }
}

I then created a simple controller to return a View:

 public class ImageSliderBlockController : BlockController<ImageSliderBlock>  
{
public override ActionResult Index(ImageSliderBlock currentBlock)
{
return PartialView(currentBlock);
}
}

And then created a strongly typed View. I gave it an Id

 @model ImageSliderBlock  
<div id="home_slideshow">
<ul class="slideshow show-buttons">
@foreach (var image in Model.Images)
{
<li>
<a href="@image.Href">
<img src="@image.GetMappedHref()"/>
</a>
</li>
}
</ul>
</div>

The Styles and JS will do the trick of displaying these images in the form of a slideshow.
For those who need these files, hit me up!

Meanwhile, in the EPiServer Edit View of the block, you can now drop images in the block!

EPiServer: Attach Database Failed – Access is Denied

I wanted to explore the EPiServer 8.0 database and so I went to clone the MDF file located within my solution and placed the copy in a backup folder. I then went to open SQL Management studio and tried attaching the MDF file:

1. Right Click on the Databases folder
2. Click ‘Attach’
3. Find the ‘Add’ button and click it where a File Browser window will open
4. Locate the file and click OK

However, I got an error along the lines of: “Attach Database failed – Unable to open the physical file – Access is denied”

Two things I did to make it work:

1. Move the .mdf file to the correct SQL path

I moved the mdf file to the following path (I’m using SQL Express):
C:Program FilesMicrosoft SQL ServerMSSQL11.SQLEXPRESSMSSQLDATA
For the full SQL, it should be something like:
C:Program FilesMicrosoft SQL ServerMSSQL11.SS2012MSSQLDATA

And then did the same steps to attach a DB file above. However, I was still getting the same error. So I went to try this next step

2. Run SQL Server Management Studio as Admin. Did the same steps as above and voila. It worked.

I tried doing only step 2 without 1 but it fails. So the solution is basically a combo of both steps.

EPiServer: Auto-create child pages on ‘Add New Page’

I spent almost a day trying to figure this out. I’ve seen heaps of examples on the internet on how to programmatically create pages in EPiServer, but it was a struggle finding a resource that explained where we can do this. Or where we can insert such code. When I finally found a solution, I felt proud. And happy. And this lead me to creating a new blog. Yay for my very first post!

Problem: On add of a new page via the EPiServer Edit page, the system should determine if the page type selected requires children to be created automatically under it.

Solution: We need two things: A new Attribute that can be attached to page types. And a class of the IInitializableModule (EPiServer.Framework) which intercepts creation of pages, checking if the page type has this new Attribute. If it does, it will call a method that will create children under it.

Sounds simple right? But I was new to EPiServer, still am actually. So I thought of creating a blog where I can write about my journeys in EPiServer hoping that someday these struggles I have and the ones I will be going through can be avoided in the future by someone like you who happens to have found my page.

So here’s how my Attribute class looks like

 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]  
public class EnsureSubPageAttribute : Attribute
{
public Type PageType { get; set; }
public string PageName { get; set; }
public string UrlSegment { get; set; }
public int SortIndex { get; set; }
public string SetReferenceToProperty { get; set; }
public string[] SetPropertyNames { get; set; }
public string[] SetPropertyValues { get; set; }
}

And then create a Class that goes by the interface IInitializableModule.
Implement members by attaching an event handler when a page is created.

 [InitializableModule]  
public class EnsureSubPages : IInitializableModule
{
#region IInitializableModule Members
public void Initialize(InitializationEngine context)
{
DataFactory.Instance.CreatedPage += Instance_CreatedPage;
}
public void Uninitialize(InitializationEngine context)
{
DataFactory.Instance.CreatedPage -= Instance_CreatedPage;
}
#endregion

Then of course, implement the event handler method.

Once this is implemented, we go ahead and attach the attribute to the appropriate page types.
Here’s an example:

 [EnsureSubPage(  
PageType = typeof(ChildPage),
UrlSegment = "give-it-a-url")]
public class AutoParentPage : SitePageData
{
}

Any questions, just comment! Thanks