<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Azzlack</title> <link>https://world.optimizely.com/blogs/Azzlack/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>Custom Error Pages in EPiServer</title>            <link>http://www.eyecatch.no/blog/custom-error-pages-in-episerver/</link>            <description>&lt;p&gt;Recently, we got a request from a customer to create custom error pages for their EPiServer website. Their requirements were that they should be able to set different error pages for different areas of the website and be able to edit the error page (meaning heading and rich bodytext).&lt;/p&gt;
&lt;p&gt;This may sound straightforward, but it did prove to be a little tricky. EPiServer has it&#39;s own error page handling, and IIS has two different elements for custom error handling (&amp;lt;customErrors /&amp;gt; and &amp;lt;httpErrors /&amp;gt;). In addition, ASP.NET performs a 302 redirect to the error pages specified in &quot;&amp;lt;customErrors /&amp;gt;&quot; which is not good for SEO.&lt;/p&gt;
&lt;p&gt;I.e: If someone links to a page that does not exist on your site, Google would follow that link. If that link then turns into a 302 temporary redirect, Google would put that page (which does not exist) into it&#39;s index. And you don&#39;t want that. It doesn&#39;t matter if it ends up with a 404 status code at the last page, Google still indexes that first page.&lt;/p&gt;
&lt;p&gt;With that in mind, you have at least two ways of rolling your own custom error handling. You can either do everything yourself by hooking into the Application_Error event in global.asax, or try to configure the IIS error handling. In this blog post I will focus on how to do the latter.&lt;/p&gt;
&lt;p&gt;First off, you need to disable the EPiServer error handling. You do that by opening your episerver.config and&#160;setting the &quot;globalErrorHandling&quot; attribute on the &quot;&amp;lt;siteSettings /&amp;gt;&quot; element to &quot;Off&quot;.&lt;/p&gt;
&lt;p&gt;Then you open web.config and&#160;find the&#160;&quot;&amp;lt;customErrors /&amp;gt;&quot; element.&#160;Ensure&#160;that&#160;the &quot;mode&quot; attribute to &quot;RemoteOnly&quot;. (This is&#160;the default mode)&lt;/p&gt;
&lt;p&gt;Now you need to create an error handler that will be the target of all&#160;errors that happen on your site. Create a page named &quot;ErrorHandler.aspx&quot; inside &quot;/Templates/ErrorPages&quot; and make&#160;it derive from EPiServer.TemplatePage.&#160;Add the following code to the class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Handles the Init event of the Page control.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;sender&quot;&amp;gt;The source of the event.&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;e&quot;&amp;gt;The &amp;lt;see cref=&quot;System.EventArgs&quot;/&amp;gt; instance containing the event data.&amp;lt;/param&amp;gt;
protected void Page_Init(object sender, EventArgs e)
{
    var statusCode = this.GetStatusCode(Request.QueryString);
    var originalPage = this.GetOriginalPage(Request.QueryString);

    if (statusCode != 0)
    {
        var errorPage = this.GetErrorPage(originalPage, statusCode);

        if (errorPage != null)
        {
            CurrentPage = errorPage;
        }
    }
}

/// &amp;lt;summary&amp;gt;
/// Gets the HTTP status code from the query string.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;queryString&quot;&amp;gt;The query string.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The HTTP status code&amp;lt;/returns&amp;gt;
private int GetStatusCode(NameValueCollection queryString)
{
    var requestQueryStrings = string.Empty;

    // Try to get query string value in two different ways
    if (queryString.GetKey(0) != null)
    {
        requestQueryStrings = queryString.GetKey(0);
    }
    else if (queryString[0] != null)
    {
        requestQueryStrings = queryString[0];
    }

    if (requestQueryStrings.Split(&#39;;&#39;).Length &amp;gt; 0)
    {
        int code;

        if (int.TryParse(requestQueryStrings.Split(&#39;;&#39;)[0], out code))
        {
            return code;
        }
    }

    return 0;
}

/// &amp;lt;summary&amp;gt;
/// Gets the original page where the error occured.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;queryString&quot;&amp;gt;The query string.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The originating page&amp;lt;/returns&amp;gt;
private PageData GetOriginalPage(NameValueCollection queryString)
{
    int pageId;

    if (int.TryParse(queryString[0], out pageId)) 
    {
        return this.GetPage(new PageReference(pageId));
    }

    return CurrentPage;
}

/// &amp;lt;summary&amp;gt;
/// Gets the correct error page for the specified HTTP status.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;originalPage&quot;&amp;gt;The original page.&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;statusCode&quot;&amp;gt;The status code.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The error page&amp;lt;/returns&amp;gt;
private PageData GetErrorPage(PageData originalPage, int statusCode)
{
    switch (statusCode)
    {
        case 404:
            Response.StatusCode = 404;
            Response.StatusDescription = &quot;Not Found&quot;;
            return this.GetPageFromProperty(originalPage, &quot;ErrorPage404&quot;);
        case 500:
            Response.StatusCode = 500;
            Response.StatusDescription = &quot;Internal Server Error&quot;;
            return this.GetPageFromProperty(originalPage, &quot;ErrorPage500&quot;);
        default:
            Response.StatusCode = 500;
            Response.StatusDescription = &quot;Internal Server Error&quot;;
            return this.GetPageFromProperty(originalPage, &quot;ErrorPage500&quot;);
    }
}

/// &amp;lt;summary&amp;gt;
/// Gets an error page from a page property.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;page&quot;&amp;gt;The page.&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;propertyName&quot;&amp;gt;Name of the property.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The error page&amp;lt;/returns&amp;gt;
private PageData GetPageFromProperty(PageData page, string propertyName)
{
    var errorPageRef = page[propertyName] as PageReference;

    return !PageReference.IsNullOrEmpty(errorPageRef) ? GetPage(errorPageRef) : null;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you take a closer look, you&#39;ll see that I try to get the error code in two different ways. That is because the 500 error query string and the 404 query strings are a little bit different. There are probably smarter ways to do this, but it solved the problem for me. The strings &quot;ErrorPage500&quot; and &quot;ErrorPage404&quot; are references to Dynamic Properties which we will configure later.&lt;/p&gt;
&lt;p&gt;Now it&#39;s time to set the front end of the ErrorHandler page. This will decide how your error pages will look. I have a very simple page that only shows a heading and some text:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; ErrorPage=&quot;~/Error.htm&quot; CodeBehind=&quot;ErrorHandler.aspx.cs&quot; Inherits=&quot;EyeCatch.EpiServer.CustomErrorPage.Templates.ErrorPages.ErrorHandler&quot; %&amp;gt;
&amp;lt;asp:Content ID=&quot;Content1&quot; ContentPlaceHolderID=&quot;plContent&quot; runat=&quot;server&quot;&amp;gt;
    &amp;lt;h1&amp;gt;&amp;lt;EPiServer:Property ID=&quot;Property1&quot; PropertyName=&quot;Heading&quot; runat=&quot;server&quot; /&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;EPiServer:Property ID=&quot;Property2&quot; PropertyName=&quot;MainBody&quot; runat=&quot;server&quot; /&amp;gt;
&amp;lt;/asp:Content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;EDIT: Added ErrorPage property to the @Page directive, after tip from Tom Pipe in the comments below.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: The only thing you need to copy from the above sample is the &quot;ErrorPage&quot; property in the @Page directive. This is a pointer to a static HTML file that will act as a fallback if EPiServer has problems. The rest of the content of your ErrorHandler.aspx file you can customize yourself.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The ErrorHandler page we&#39;ve just created however, will never&#160;be tied to a Page Type or template. For that we create two&#160;new template pages named &quot;ErrorPage.aspx&quot; and &quot;NotFoundPage.aspx&quot;.&lt;/p&gt;
&lt;p&gt;Add the above HTML to those pages as well (Don&#39;t copy&#160;the codebehind and the @Page directive, this should be left as it is&#160;when you create the file).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;NOTE: The above step is not needed for this to work, but it enables editors to see what the resulting error page looks like. The only thing you need is for&#160;404 and 500&#160;page&#160;types&#160;to have the properties defined in ErrorHandler.aspx&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now go to EPiServer and create a Page Type&#160;that look like this:&lt;/p&gt;
&lt;p&gt;&#160;&lt;img style=&quot;width: 500px; height:265.7430730478589px;&quot; src=&quot;http://blob.eyecatch.no/media/1022/epi_pagetype_settings-1.png?width=500&amp;amp;height=265.7430730478589&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Properties:&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;width: 500px; height:91.70854271356785px;&quot; src=&quot;http://blob.eyecatch.no/media/1023/epi_pagetype_properties-1.png?width=500&amp;amp;height=91.70854271356785&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Do the same for the Not Found page, only exchange &quot;ErrorPage&quot; with &quot;NotFoundPage&quot;.&lt;/p&gt;
&lt;p&gt;Now you need to add some dynamic properties. Click on the &quot;Dynamic Properties&quot; link and then press &quot;Add Property&quot;. Create a property that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;width: 500px; height:270.96370463078847px;&quot; src=&quot;http://blob.eyecatch.no/media/1024/epi_dyn_property-1.png?width=500&amp;amp;height=270.96370463078847&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Do the same for the 500 Error Page, just change &quot;ErrorPage404&quot; to &quot;ErrorPage500&quot; and &quot;404 Error Page&quot; to &quot;500 Error Page&quot;.&lt;/p&gt;
&lt;p&gt;With that done we can go on to create&#160;the actual&#160;error pages and set the dynamic properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create&#160;two pages of type &quot;[Web] ErrorPage&quot; and &quot;[Web] NotFoundPage&quot; somewhere in your site tree. (I created them right under the root node). Fill in the heading and body text (you can also insert an image if you like). Publish the pages.&lt;/li&gt;
&lt;li&gt;Click your root node and then click on the &quot;Dynamic Properties&quot; icon on the toolbar. (The one with 3 blocks on it)&lt;/li&gt;
&lt;li&gt;Set the &quot;404 Not Found Page&quot; and &quot;500 Error Page&quot; properties to the pages you just created. Click &quot;Save&quot;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now it&#39;s time to return to web.config and do the last configuration. You can also perform this step from within IIS Manager, but I&#39;m going to show the web.config way. (The result is the same).&lt;/p&gt;
&lt;p&gt;Insert the following&#160;block at the end of the &quot;&amp;lt;system.webServer /&amp;gt;&quot; block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;httpErrors errorMode=&quot;Custom&quot; existingResponse=&quot;Replace&quot;&amp;gt;
    &amp;lt;remove statusCode=&quot;404&quot; subStatusCode=&quot;-1&quot; /&amp;gt;
    &amp;lt;remove statusCode=&quot;500&quot; subStatusCode=&quot;-1&quot; /&amp;gt;
    &amp;lt;error statusCode=&quot;404&quot; prefixLanguageFilePath=&quot;&quot; path=&quot;/Templates/ErrorPages/ErrorHandler.aspx&quot; responseMode=&quot;ExecuteURL&quot; /&amp;gt;
    &amp;lt;error statusCode=&quot;500&quot; prefixLanguageFilePath=&quot;&quot; path=&quot;/Templates/ErrorPages/ErrorHandler.aspx&quot; responseMode=&quot;ExecuteURL&quot; /&amp;gt;
&amp;lt;/httpErrors&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you&#39;re done!&lt;/p&gt;
&lt;p&gt;If you didn&#39;t understand what you just did, here is a walkthrough:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An error occurs on your site (404 Not Found&#160;or 500 Internal Server Error).&lt;/li&gt;
&lt;li&gt;Since EPiServer is not doing any error handling, the event bubbles up to IIS.&lt;/li&gt;
&lt;li&gt;IIS looks at the &amp;lt;httpErrors /&amp;gt; element and executes the URL that is specified for the HTTP status code.&lt;/li&gt;
&lt;li&gt;It loads &quot;ErrorHandler.aspx&quot; directly (no redirects).&lt;/li&gt;
&lt;li&gt;During the initialization of the ErrorHandler page, it checks what kind of error occured (404 or 500).&lt;/li&gt;
&lt;li&gt;It then gets the page referenced in the Dynamic Property&#160;and loads the&#160;&lt;em&gt;PageData&lt;/em&gt;&#160;for that page (Heading and BodyText).&lt;/li&gt;
&lt;li&gt;ErrorHandler then inserts the Heading and the BodyText into the corresponding elements in the ErrorHandler designer.&lt;/li&gt;
&lt;li&gt;The page is then loaded with your chosen text and with no ugly redirects.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;I hope this tutorial is of use to you. If you have any questions or comments, don&#39;t hestitate to use the comment form below.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;</description>            <guid>http://www.eyecatch.no/blog/custom-error-pages-in-episerver/</guid>            <pubDate>Wed, 05 Aug 2015 01:48:47 GMT</pubDate>           <category>Blog post</category></item><item> <title>Using XForms and MVC in EPiServer 7</title>            <link>http://www.eyecatch.no/blog/using-xforms-and-mvc-in-episerver-7/</link>            <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: Updated blog post to solve issues and questions posted in the comment section, as well as generalizing it to work with XForm instances on pages as well. This version also supports redirection after form submission as well as proper validation.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The most awesome features of EpiServer 7 is arguably it&#39;s Block system and that it&#39;s possible to use MVC when developing sites.&lt;/p&gt;
&lt;p&gt;Alas, some things in EPiServer 7 apparently has some issues when it comes to supporting MVC - XForms being one of them.&lt;/p&gt;
&lt;p&gt;For one thing, XForms requires that you post to a url. That means you need to post to an instance of a page, or create a standalone controller for handling xform requests only.&lt;/p&gt;
&lt;p&gt;This blog post will show you how to set up XForms using the former method.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;First off, you need to create a base controller that all your pages must derive from:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;public abstract class BasePageController&amp;lt;T&amp;gt; : PageController&amp;lt;T&amp;gt; where T : PageData
{
    /// &amp;lt;summary&amp;gt;
    /// The view data key format
    /// &amp;lt;/summary&amp;gt;
    private const string ViewDataKeyFormat = &quot;TempViewData_{0}&quot;;

    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the &amp;lt;see cref=&quot;BasePageController{T}&quot; /&amp;gt; class.
    /// &amp;lt;/summary&amp;gt;
    protected BasePageController()
    {
        this.ContentId = string.Empty;
    }
    
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the data factory
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The content repository.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public IContentRepository ContentRepository { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the page route helper repository.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The page route helper repository.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public PageRouteHelper PageRouteHelperRepository { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the URL resolver.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The URL resolver.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public UrlResolver UrlResolver { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the xform handler.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The xform handler.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public XFormPageUnknownActionHandler XFormHandler { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the current page.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The current page.&amp;lt;/value&amp;gt;
    public PageData CurrentPage { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets a value indicating whether the block [is in edit mode].
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if the block [is in edit mode]; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.&amp;lt;/returns&amp;gt;
    protected bool IsInEditMode
    {
        get
        {
            return PageEditing.GetPageIsInEditMode(this.HttpContext);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets the view data key.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The view data key.&amp;lt;/value&amp;gt;
    private string ViewDataKey
    {
        get
        {
            return string.Format(ViewDataKeyFormat, this.ContentId);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the content id
    /// &amp;lt;/summary&amp;gt;
    private string ContentId
    {
        get
        {
            return this.TempData[&quot;ContentID&quot;] != null ? this.TempData[&quot;ContentID&quot;].ToString() : (this.TempData[&quot;ContentID&quot;] = string.Empty).ToString();
        }

        set
        {
            this.TempData[&quot;ContentID&quot;] = value;
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;data&quot;&amp;gt;The posted form data.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&quot;contentId&quot;&amp;gt;The block id.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;A view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult XFormPost(XFormPostedData data, string contentId = &quot;&quot;)
    {
        if (!string.IsNullOrEmpty(contentId)) 
        {
            this.ContentId = contentId;
        }

        // Add posted xform instance id to viewdata, so we can retrieve it later
        this.ViewData[&quot;XFormID&quot;] = data.XForm.Id;

        return this.XFormHandler.HandleAction(this);
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback if it was successful.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;data&quot;&amp;gt;The posted form data.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;A view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Success(XFormPostedData data)
    {
        if (data.XForm.PageGuidAfterPost != Guid.Empty)
        {
            var page = this.ContentRepository.Get&amp;lt;PageData&amp;gt;(data.XForm.PageGuidAfterPost);

            return this.Redirect(this.UrlResolver.GetVirtualPath(page.ContentLink, page.LanguageBranch));
        }

        return this.Redirect(this.UrlResolver.GetVirtualPath(this.CurrentPage.ContentLink, this.CurrentPage.LanguageBranch));
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback if it was successful.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;data&quot;&amp;gt;The posted form data.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;A view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Failed(XFormPostedData data)
    {
        return this.Redirect(this.UrlResolver.GetVirtualPath(this.CurrentPage.ContentLink, this.CurrentPage.LanguageBranch));
    }

    /// &amp;lt;summary&amp;gt;
    /// Called before the action method is invoked.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;filterContext&quot;&amp;gt;Information about the current request and action.&amp;lt;/param&amp;gt;
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Get current page
        this.CurrentPage = this.PageRouteHelperRepository.Page;

        // Set content id if it has not been set
        if (string.IsNullOrEmpty(this.ContentId))
        {
            this.ContentId = this.CurrentPage.PageLink.ID.ToString();
        }

        // Persist view data if this is a failed or successful xform postback, reset if this is a new postback
        if (filterContext.ActionDescriptor.ActionName == &quot;Failed&quot;
            || filterContext.ActionDescriptor.ActionName == &quot;Success&quot;)
        {
            this.TempData[this.ViewDataKey] = this.ViewData;
        }
        else if (filterContext.ActionDescriptor.ActionName == &quot;XFormPost&quot;)
        {
            this.TempData[this.ViewDataKey] = null;
        }
        
        // Merge tempdata into viewdata if it is not null
        var tempData = this.TempData[this.ViewDataKey] as ViewDataDictionary;

        if (tempData != null)
        {
            this.ViewData = tempData;
        }

        base.OnActionExecuting(filterContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h4&gt;Making it work with pages&lt;/h4&gt;
&lt;p&gt;Create a page type class like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ContentType(DisplayName = &quot;XForm Page&quot;)]
public class XFormPage
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;The form&quot;,
        Description = &quot;The form.&quot;,
        GroupName = SystemTabNames.Content,
        Order = 1)]
    [CultureSpecific]
    public virtual XForm Schema { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you need to display the form on the page.&lt;br /&gt;Create a ViewModel class for your page type class:&#160;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;public class XFormPageViewModel : BasePageViewModel
{
&#160; &#160; public XForm Schema { get; set; }

&#160; &#160; public string ActionUrl { get; set; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then create a page controller that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class XFormPageController : BasePageController&amp;lt;XFormPage&amp;gt;
{
    private readonly UrlResolver urlResolver;

    public XFormPageController(UrlResolver urlResolver)
    {
        this.urlResolver = urlResolver;
    }

    public ActionResult Index(XFormPage currentPage)
    {
        var viewModel = new XFormPageViewModel()
                            {
                                Schema = currentPage.Schema
                            };

        if (currentPage.Schema != null)
        {
            var actionUrl = string.Format(&quot;{0}XFormPost/&quot;, this.urlResolver.GetVirtualPath(currentPage.PageLink, currentPage.LanguageBranch));
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;XFormId&quot;, viewModel.Schema.Id.ToString());
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;failedAction&quot;, &quot;Failed&quot;);
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;successAction&quot;, &quot;Success&quot;);

            viewModel.ActionUrl = actionUrl;
        }

        var editHints = this.ViewData.GetEditHints&amp;lt;XFormPageViewModel, XFormPage&amp;gt;();
        editHints.AddConnection(v =&amp;gt; v.Schema, p =&amp;gt; p.Schema);

        return this.View(viewModel);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could avoid using a viewmodel like the one above and just use the page type as a viewmodel, but I like to adhere to the MVVM model and I want to be able to set a custom css class for an instance of the page.&lt;/p&gt;
&lt;p&gt;Now we need to create a view. (If you&#39;re using ReSharper, just ALT+ENTER on the &quot;return this.View(viewModel)&quot; line)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.Web.Mvc.Html
@model EPiServer.Demo.TwitterBootstrap.ViewModels.Pages.XFormPageViewModel

&amp;lt;div class=&quot;xformpage&quot; @Html.EditAttributes(x =&amp;gt; x.Schema)&amp;gt;
    @using (Html.BeginXForm(Model.Schema, new { Action = Model.ActionUrl, @class = &quot;form xform&quot; }))
    {
        Html.RenderXForm(Model.Schema);
    }
    if (Model.Schema.Id == ViewData[&quot;XFormID&quot;])
    {
        @Html.ValidationSummary()
    }
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note:&#160;Html.ValidationSummary()&#160;is wrapped&#160;in an&#160;if&#160;statement to prevent the validation summary from showing errors from other forms on the same page.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now you&#39;re ready to go. Just create an instance of a XFormPage, add a form to it and try i out.&#160;&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h4&gt;Making it work with Blocks&lt;/h4&gt;
&lt;p&gt;This is very similar to making it work with pages, you just need one more parameter on the action url.&lt;/p&gt;
&lt;p&gt;First off, you need to create your Block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ContentType(DisplayName = &quot;XForm block&quot;)]
public class XFormBlock : BlockData
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;The form&quot;,
        Description = &quot;The form.&quot;,
        GroupName = SystemTabNames.Content,
        Order = 1)]
    [CultureSpecific]
    public virtual XForm Schema { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the corresponding viewmodel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class XFormBlockViewModel
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    public XForm Schema { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the action URI.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The action URI.&amp;lt;/value&amp;gt;
    public string ActionUri { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you need to create a controller for showing the block on a page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class XFormBlockController : BlockController&amp;lt;XFormBlock&amp;gt;
{
    private readonly PageRouteHelper pageRouteHelper;

    private readonly UrlResolver urlResolver;

    public XFormBlockController(PageRouteHelper pageRouteHelper, UrlResolver urlResolver)
    {
        this.pageRouteHelper = pageRouteHelper;
        this.urlResolver = urlResolver;
    }

    public override ActionResult Index(XFormBlock currentBlock)
    {
        var id = (currentBlock as IContent).ContentLink.ID;

        // ViewData is not automatically passed to a block controller, need to get it from TempData if it exists
        var viewDataKey = string.Format(&quot;TempViewData_{0}&quot;, id);

        if (this.TempData[viewDataKey] != null)
        {
            this.ViewData = (ViewDataDictionary)this.TempData[viewDataKey];
        }

        // Create the viewmodel
        var viewModel = new XFormBlockViewModel()
                            {
                                Schema = currentBlock.Schema
                            };

        // Create postback url
        if (viewModel.Schema != null &amp;amp;&amp;amp; this.pageRouteHelper.Page != null)
        {
            var actionUrl = string.Format(&quot;{0}XFormPost/&quot;, this.urlResolver.GetVirtualPath(this.pageRouteHelper.Page.PageLink, this.pageRouteHelper.Page.LanguageBranch));
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;XFormId&quot;, viewModel.Schema.Id.ToString());
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;failedAction&quot;, &quot;Failed&quot;);
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;successAction&quot;, &quot;Success&quot;);
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;contentId&quot;, id.ToString());

            viewModel.ActionUri = actionUrl;
        }

        var editHints = this.ViewData.GetEditHints&amp;lt;XFormBlockViewModel, XFormBlock&amp;gt;();
        editHints.AddConnection(v =&amp;gt; v.Schema, p =&amp;gt; p.Schema);

        return this.PartialView(viewModel);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When that&#39;s done, create the partial view for the block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.Web.Mvc.Html
@model EPiServer.Demo.TwitterBootstrap.ViewModels.Partials.XFormViewModel

&amp;lt;div class=&quot;xformblock&quot; @Html.EditAttributes(x =&amp;gt; x.Schema)&amp;gt;
    @using (Html.BeginXForm(Model.Schema, new { Action = Model.ActionUri, @class = &quot;form xform&quot; }))
    {
        Html.RenderXForm(Model.Schema);
    }
    if (Model.Schema.Id == ViewData[&quot;XFormID&quot;])
    {
        @Html.ValidationSummary()
    }
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: There is an issue with using the built-in XForm display template and multiple XForm blocks on the same page. Basically, it will replace the contents of all other forms with the content of the posted form on postback.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To solve this, put the following code in a file named XForm.cshtml in a folder called DisplayTemplates in your ~/Views/Shared folder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.HtmlParsing
@using Leroy.Web.EPiServer.BusinessLogic.Extensions
@model EPiServer.XForms.XForm
           
@if (Model != null)
{
    var fragments = Model.CreateHtmlFragments();

    // Check if this is a postback, and if it is get the posted fragments for this instance
    if (ViewData[&quot;XFormID&quot;] != null &amp;amp;&amp;amp; Model.Id == ViewData[&quot;XFormID&quot;])
    {
        fragments = (IEnumerable&amp;lt;HtmlFragment&amp;gt;)ViewData[&quot;XFormFragments&quot;];
    }
    
    // Render all fragments
    foreach (var fragment in fragments)
    {
        @Html.RenderCustomHtmlFragment(fragment, &quot;XForm/&quot; + Model.Id + &quot;/&quot; + fragment.GetType().Name)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is all. Now you just need to add your XFormBlock to a page using a ContentArea, and the XFormBlockController will take care of rendering the form.&lt;/p&gt;
&lt;p&gt;When the user submits the form, the BasePageController will take care of storing the data and/or sending emails, etc.&lt;/p&gt;
&lt;p&gt;Stay tuned for the next blog post where I&#39;ll show you how to completely customize the rendering of the form based on the built-in MVC rendering engine. :-)&lt;/p&gt;</description>            <guid>http://www.eyecatch.no/blog/using-xforms-and-mvc-in-episerver-7/</guid>            <pubDate>Wed, 05 Aug 2015 01:17:51 GMT</pubDate>           <category>Blog post</category></item><item> <title>Full customization of XForms with EPiServer 7 and MVC</title>            <link>http://www.eyecatch.no/blog/full-customization-of-xforms-with-episerver-7-and-mvc/</link>            <description>&lt;p&gt;By default ASP.Net MVC uses conventions for locating the correct view for a controller action. But MVC comes with a nifty feature that lets you register custom view location rules, and this blog post will show you how to utilize that to completely customize the XForm html.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: The below step for forcing EPiServer to look in ~/Views/Shared/DisplayTemplates and&#160;~/Views/Shared/EditorTemplates for templates is not needed from version 7.5 and upwards.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;First we need to register a custom view locator. To do that you need to hook into the application startup events, and I will use the excellent &lt;span class=&quot;code&quot;&gt;WebActivator&lt;/span&gt; package for this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;using EPiServer.Demo.TwitterBootstrap;

[assembly: WebActivator.PreApplicationStartMethod(typeof(HtmlFragmentViewEngineBoostrapper), &quot;PreStart&quot;)]

namespace EPiServer.Demo.TwitterBootstrap
{
&#160; &#160; using System.Web.Mvc;

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Bootstrapper for configuring the razor view engine for HtmlFragment views
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; public class HtmlFragmentViewEngineBoostrapper
&#160; &#160; {
&#160; &#160; &#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; &#160; &#160; /// Occurs before the application starts
&#160; &#160; &#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; &#160; &#160; public static void PreStart()
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; var engine = new RazorViewEngine()
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;{
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;PartialViewLocationFormats =
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;new[]
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;{
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{0}.vbhtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{1}/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{1}/{0}.vbhtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{0}.vbhtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{1}/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{1}/{0}.vbhtml&quot;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;}
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;};

&#160; &#160; &#160; &#160; &#160; &#160; ViewEngines.Engines.Add(engine);
&#160; &#160; &#160; &#160; }
&#160; &#160; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note: HtmlFragment is the XForm &quot;fragments&quot; (table rows, input boxes, etc.)&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Note2: {1} in the location format is the Controller name and {0} is the name of the view.&#160;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: Some people have been asking me why the need for the below extension methods.&#160;&lt;br /&gt;The answer is that XForm does not support having different editor templates for different forms out of the box. The class below lets us specify a folder where it should look for the editor templates before falling back on the built-in ones. You will find examples on how to use it later in this article.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We also need to create an extension to replace EPiServers own RenderXForm html helpers:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;/// &amp;lt;summary&amp;gt;
/// Extensions for the &amp;lt;see cref=&quot;HtmlHelper&quot;/&amp;gt; class
/// &amp;lt;/summary&amp;gt;
public static class HtmlFragmentExtensions
{
&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Writes the XForm to the view context&#39;s output steam.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper instance that this method extends.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;xform&quot;&amp;gt;The XForm to write.&amp;lt;/param&amp;gt;
&#160; &#160; public static void RenderCustomXForm(this HtmlHelper htmlHelper, XForm xform)
&#160; &#160; {
&#160; &#160; &#160; &#160; if (xform == null)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; return;
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; htmlHelper.RenderCustomXForm(xform, new XFormParameters());
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Writes the XForm to the view context&#39;s output steam.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper instance that this method extends.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;xform&quot;&amp;gt;The XForm to write.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;parameters&quot;&amp;gt;The parameters to be used by the XForm.&amp;lt;/param&amp;gt;
&#160; &#160; public static void RenderCustomXForm(this HtmlHelper htmlHelper, XForm xform, XFormParameters parameters)
&#160; &#160; {
&#160; &#160; &#160; &#160; if (xform == null)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; return;
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; htmlHelper.ViewContext.ViewData[&quot;XFormParameters&quot;] = parameters;

&#160; &#160; &#160; &#160; htmlHelper.RenderPartial(typeof(XForm).Name, xform);
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Renders the html fragment.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;fragment&quot;&amp;gt;The fragment.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;renderFragmentsWithoutView&quot;&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; [render fragments without view].&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;returns&amp;gt;A HTML-encoded string.&amp;lt;/returns&amp;gt;
&#160; &#160; public static MvcHtmlString RenderCustomHtmlFragment(this HtmlHelper htmlHelper, HtmlFragment fragment, bool renderFragmentsWithoutView = true)
&#160; &#160; {
&#160; &#160; &#160; &#160; var value = new StringBuilder();

&#160; &#160; &#160; &#160; using (var writer = new StringWriter(value))
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; // Try to find a matching partial view
&#160; &#160; &#160; &#160; &#160; &#160; var viewEngineResult = ViewEngines.Engines.FindPartialView(htmlHelper.ViewContext, fragment.GetType().Name);

&#160; &#160; &#160; &#160; &#160; &#160; if (viewEngineResult.View != null)
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; viewEngineResult.View.Render(viewEngineResult, htmlHelper.ViewContext, writer, fragment);
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; &#160; &#160; else if (renderFragmentsWithoutView)
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // Render fragment directly unless otherwise specified
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; writer.Write(fragment.ToString());
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; return value.Length &amp;lt;= 0 ? MvcHtmlString.Empty : MvcHtmlString.Create(value.ToString());
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Renders the HTML fragment.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;fragment&quot;&amp;gt;The fragment.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;partialViewName&quot;&amp;gt;The partial view name.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;useFallback&quot;&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; [use fallback].&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;renderFragmentsWithoutView&quot;&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; [render fragments without view].&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;returns&amp;gt;A HTML-encoded string.&amp;lt;/returns&amp;gt;
&#160; &#160; public static MvcHtmlString RenderCustomHtmlFragment(this HtmlHelper htmlHelper, HtmlFragment fragment, string partialViewName, bool useFallback = true, bool renderFragmentsWithoutView = true)
&#160; &#160; {
&#160; &#160; &#160; &#160; var value = new StringBuilder();

&#160; &#160; &#160; &#160; using (var writer = new StringWriter(value))
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; // Try to find a matching partial view
&#160; &#160; &#160; &#160; &#160; &#160; var viewEngineResult = ViewEngines.Engines.FindPartialView(htmlHelper.ViewContext, partialViewName);

&#160; &#160; &#160; &#160; &#160; &#160; if (viewEngineResult.View != null)
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; viewEngineResult.View.Render(viewEngineResult, htmlHelper.ViewContext, writer, fragment);
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; &#160; &#160; else
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // Try to fall back to default view
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (useFallback)
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; return htmlHelper.RenderCustomHtmlFragment(fragment, renderFragmentsWithoutView);
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // Render fragment directly unless otherwise specified
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (renderFragmentsWithoutView)
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; writer.Write(fragment.ToString());
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; return value.Length &amp;lt;= 0 ? MvcHtmlString.Empty : MvcHtmlString.Create(value.ToString());
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Renders the HTML fragment.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;view&quot;&amp;gt;The view.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;viewEngineResult&quot;&amp;gt;The view engine result.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;context&quot;&amp;gt;The context.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;writer&quot;&amp;gt;The writer.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;fragment&quot;&amp;gt;The fragment.&amp;lt;/param&amp;gt;
&#160; &#160; private static void Render(this IView view, ViewEngineResult viewEngineResult, ViewContext context, TextWriter writer, HtmlFragment fragment)
&#160; &#160; {
&#160; &#160; &#160; &#160; var viewDataDictionaries = new ViewDataDictionary(fragment);

&#160; &#160; &#160; &#160; foreach (var viewDatum in context.ViewData)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; viewDataDictionaries[viewDatum.Key] = viewDatum.Value;
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; var viewContext = new ViewContext(context, viewEngineResult.View, viewDataDictionaries, context.TempData, writer);

&#160; &#160; &#160; &#160; foreach (var modelState in context.ViewData.ModelState)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; viewContext.ViewData.ModelState.Add(modelState.Key, modelState.Value);
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; viewEngineResult.View.Render(viewContext, writer);
&#160; &#160; &#160; &#160; viewEngineResult.ViewEngine.ReleaseView(context.Controller.ControllerContext, viewEngineResult.View);
&#160; &#160; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What this allows us is to override the renderer for XForm in general. We can now use the following code to render an XForm:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(view code taken from&#160;&lt;a href=&quot;#&quot; title=&quot;Using XForms and MVC in an EPiServer 7 Block&quot;&gt;previous blog post about XForms and MVC&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.Web.Mvc.Html
@model EPiServer.Demo.TwitterBootstrap.ViewModels.Partials.XFormBlockViewModel

&amp;lt;div class=&quot;xformpage&quot; @Html.EditAttributes(x =&amp;gt; x.Schema)&amp;gt;
&#160; &#160; @using (Html.BeginXForm(Model.Schema, new { Action = Model.ActionUrl, @class = &quot;form xform&quot; }))
&#160; &#160; {
&#160; &#160; &#160; &#160; Html.RenderCustomXForm(Model.Schema);
&#160; &#160; }
&#160; &#160; &#160; &#160;&#160;
&#160; &#160; if (Model.Schema.Id == ViewData[&quot;XFormID&quot;])
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.ValidationSummary()
&#160; &#160; }
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Right now this just renders the XForm with EPiServers default view, as we haven&#39;t implemented a custom view yet.&lt;br /&gt;Create a file called XForm.cshtml in ~/Views/Shared/DisplayTemplates and insert the following code in it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@using EPiServer.HtmlParsing
@model EPiServer.XForms.XForm

&amp;lt;h3&amp;gt;Custom XForm view&amp;lt;/h3&amp;gt;
@if (Model != null)
{
&#160; &#160; var fragments = Model.CreateHtmlFragments();

&#160; &#160; // Check if this is a postback, and if it is get the posted fragments for this instance
&#160; &#160; if (ViewData[&quot;XFormInstanceID&quot;] != null &amp;amp;&amp;amp; Model.Id == ViewData[&quot;XFormInstanceID&quot;])
&#160; &#160; {
&#160; &#160; &#160; &#160; fragments = (IEnumerable&amp;lt;HtmlFragment&amp;gt;)ViewData[&quot;XFormFragments&quot;];
&#160; &#160; }
&#160; &#160;&#160;
&#160; &#160; // Render all fragments
&#160; &#160; foreach (var fragment in fragments)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.RenderCustomHtmlFragment(fragment, &quot;XForm/&quot; + Model.Id + &quot;/&quot; + fragment.GetType().Name)
&#160; &#160; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you load a page with a XForm on now, you&#39;ll se a header with your xform id above your form.&lt;/p&gt;
&lt;p&gt;Now, lets say we want to utilize some bootstrap styling on our forms. That means we need to get rid of those hideous tables and replace them with our own stuff.&lt;/p&gt;
&lt;p&gt;Replace the RenderCustomHtmlFragment code in the view above with the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@Html.RenderCustomHtmlFragment(fragment, &quot;XForm/&quot; + Model.Id + &quot;/&quot; + fragment.GetType().Name)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code tells our html helper extension to look in the &quot;~/Views/Shared/DisplayTemplates/XForm/{xform-id}/&quot; folder for views for each html fragment.&lt;/p&gt;
&lt;p&gt;Create the following files in the folder mentioned above (replace {xform-id} with the id of your xform):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;InputFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.InputFragment

&amp;lt;div class=&quot;form-group @Model.Reference @Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;label for=&quot;@Model.Reference&quot;&amp;gt;@Model.Label&amp;lt;/label&amp;gt;
&#160; &#160; @if (Model.Required)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextBox(Model.Reference, Server.HtmlDecode(Model.Value) ?? string.Empty, new { @class = &quot;form-control&quot;, size = Model.Size, placeholder = Model.Title, required = &quot;required&quot; })
&#160; &#160; }
&#160; &#160; else
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextBox(Model.Reference, Server.HtmlDecode(Model.Value) ?? string.Empty, new { @class = &quot;form-control&quot;, size = Model.Size, placeholder = Model.Title })
&#160; &#160; }
&#160; &#160; @Html.ValidationMessage(Model.Reference) // EPiServer 7.0 to 7.1
&#160; &#160; @Html.ValidationMessage(Model.ValidationReference) // EPiServer 7.5 and upwards
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ElementFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.HtmlParsing.ElementFragment&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;EndElementFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.HtmlParsing.EndElementFragment&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;SubmitFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.SubmitFragment

&amp;lt;div class=&quot;@Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;input type=&quot;submit&quot; class=&quot;btn btn-default&quot; name=&quot;@Html.Raw(Model.UniqueName)&quot; title=&quot;@Html.Raw(Model.Title)&quot; value=&quot;@Html.Raw(Model.Value)&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;TextareaFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.TextareaFragment

&amp;lt;div class=&quot;form-group @Model.Reference @Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;label for=&quot;@Model.Reference&quot;&amp;gt;@Model.Label&amp;lt;/label&amp;gt;
&#160; &#160; @if (Model.Required)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextArea(Model.Reference, Model.Value, Model.Rows, Model.Columns, new { @class = &quot;form-control&quot;, placeholder = Model.Title, required = &quot;required&quot; })
&#160; &#160; }
&#160; &#160; else
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextArea(Model.Reference, Model.Value, Model.Rows, Model.Columns, new { @class=&quot;form-control&quot;, placeholder = Model.Title })
&#160; &#160; }
&#160; &#160; @Html.ValidationMessage(Model.Reference) // EPiServer 7.0 to 7.1
&#160; &#160; @Html.ValidationMessage(Model.ValidationReference) // EPiServer 7.5 and upwards
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Select1tAsDropdownListFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.Select1Fragment

&amp;lt;div class=&quot;form-group @Model.Reference @Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;label for=&quot;@Model.Reference&quot;&amp;gt;@Model.Label&amp;lt;/label&amp;gt;
&#160; &#160; @if (Model.Required)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.DropDownList(Model.Reference, Model.Options.Select(o =&amp;gt; new SelectListItem() { Text = Server.HtmlDecode(o.Text), Value = Server.HtmlDecode(o.Value), Selected = o.SelectedItem }), new { @class = &quot;form-control&quot;, @title = Model.Title, @required = &quot;required&quot; })
&#160; &#160; }
&#160; &#160; else
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.DropDownList(Model.Reference, Model.Options.Select(o =&amp;gt; new SelectListItem() { Text = Server.HtmlDecode(o.Text), Value = Server.HtmlDecode(o.Value), Selected = o.SelectedItem }), new { @class = &quot;form-control&quot;, @title = Model.Title })
&#160; &#160; }
&#160; &#160; @Html.ValidationMessage(Model.Reference) // EPiServer 7.0 to 7.1
&#160; &#160; @Html.ValidationMessage(Model.ValidationReference) // EPiServer 7.5 and upwards
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;If you render your form now, you will see that it has very different html output.&lt;br /&gt;This output is also compatible with Twitter Bootstrap and jQuery Validation, meaning you get (partial) client-side validation. Yay! :-)&lt;/p&gt;
&lt;p&gt;All this allows us to go from the following form configuration&lt;br /&gt;&lt;img style=&quot;width: 500px; height: 225.25027808676305px;&quot; src=&quot;http://blob.eyecatch.no/media/1036/form-1.png?width=500&amp;amp;height=225.25027808676305&quot; alt=&quot;&quot; /&gt;&#160;&lt;/p&gt;
&lt;p&gt;And it&#39;s default styling&lt;br /&gt;&lt;img style=&quot;width: 299px; height: 307px;&quot; src=&quot;http://blob.eyecatch.no/media/1037/form_display_before-1.png?width=299&amp;amp;height=307&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To this beautiful form&lt;br /&gt;&lt;img id=&quot;__mcenew&quot; src=&quot;http://blob.eyecatch.no/media/1038/form_display_after-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h3&gt;What more can you do?&#160;&lt;/h3&gt;
&lt;p&gt;You can override the style of all the form fields. Here is a list of file names and models of all field types:&lt;/p&gt;
&lt;table border=&quot;0&quot; class=&quot;mdl-data-table mdl-js-data-table&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;File name&lt;/th&gt;&lt;th&gt;Model&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ElementFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.HtmlParsing.ElementFragment&lt;/td&gt;
&lt;td&gt;Inserted before each &quot;fragment&quot; (row, label, textbox, etc.), and template for horizontal rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EndElementFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.HtmlParsing.EndElementFragment&lt;/td&gt;
&lt;td&gt;Inserted after each &quot;fragment&quot; (row, label, textbox, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;InputFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.InputFragment&lt;/td&gt;
&lt;td&gt;Template for every textbox field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Select1tAsDropdownListFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.Select1Fragment&lt;/td&gt;
&lt;td&gt;Template for every dropdown field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SubmitFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.SubmitFragment&lt;/td&gt;
&lt;td&gt;Template for every submit button&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TextareaFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.TextareaFragment&lt;/td&gt;
&lt;td&gt;Template for every textarea field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TextFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.HtmlParsing.TextFragment&lt;/td&gt;
&lt;td&gt;Template for every heading field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SelectFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.SelectFragment&lt;/td&gt;
&lt;td&gt;Template for every checkbox field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Select1AsRadiobuttonFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.Select1Fragment&lt;/td&gt;
&lt;td&gt;Template for every radio button field&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;NOTE: You can find the default templates for some of these at &quot;C:\Program Files (x86)\EPiServer\CMS\7.0.586.1\Application\Util\Views\Shared\EditorTemplates&quot;&lt;/em&gt;&lt;/p&gt;</description>            <guid>http://www.eyecatch.no/blog/full-customization-of-xforms-with-episerver-7-and-mvc/</guid>            <pubDate>Tue, 04 Aug 2015 19:39:32 GMT</pubDate>           <category>Blog post</category></item><item> <title>Full customization of XForms with EPiServer 7 and MVC</title>            <link>http://www.eyecatch.no/blog/full-customization-of-xforms-with-episerver-7-and-mvc/</link>            <description>&lt;p&gt;By default ASP.Net MVC uses conventions for locating the correct view for a controller action. But MVC comes with a nifty feature that lets you register custom view location rules, and this blog post will show you how to utilize that to completely customize the XForm html.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: The below step for forcing EPiServer to look in ~/Views/Shared/DisplayTemplates and&#160;~/Views/Shared/EditorTemplates for templates is not needed from version 7.5 and upwards.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;First we need to register a custom view locator. To do that you need to hook into the application startup events, and I will use the excellent &lt;span class=&quot;code&quot;&gt;WebActivator&lt;/span&gt; package for this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;using EPiServer.Demo.TwitterBootstrap;

[assembly: WebActivator.PreApplicationStartMethod(typeof(HtmlFragmentViewEngineBoostrapper), &quot;PreStart&quot;)]

namespace EPiServer.Demo.TwitterBootstrap
{
&#160; &#160; using System.Web.Mvc;

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Bootstrapper for configuring the razor view engine for HtmlFragment views
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; public class HtmlFragmentViewEngineBoostrapper
&#160; &#160; {
&#160; &#160; &#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; &#160; &#160; /// Occurs before the application starts
&#160; &#160; &#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; &#160; &#160; public static void PreStart()
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; var engine = new RazorViewEngine()
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;{
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;PartialViewLocationFormats =
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;new[]
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;{
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{0}.vbhtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{1}/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/DisplayTemplates/{1}/{0}.vbhtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{0}.vbhtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{1}/{0}.cshtml&quot;,
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&quot;~/Views/Shared/EditorTemplates/{1}/{0}.vbhtml&quot;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;}
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;};

&#160; &#160; &#160; &#160; &#160; &#160; ViewEngines.Engines.Add(engine);
&#160; &#160; &#160; &#160; }
&#160; &#160; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note: HtmlFragment is the XForm &quot;fragments&quot; (table rows, input boxes, etc.)&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Note2: {1} in the location format is the Controller name and {0} is the name of the view.&#160;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: Some people have been asking me why the need for the below extension methods.&#160;&lt;br /&gt;The answer is that XForm does not support having different editor templates for different forms out of the box. The class below lets us specify a folder where it should look for the editor templates before falling back on the built-in ones. You will find examples on how to use it later in this article.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We also need to create an extension to replace EPiServers own RenderXForm html helpers:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;/// &amp;lt;summary&amp;gt;
/// Extensions for the &amp;lt;see cref=&quot;HtmlHelper&quot;/&amp;gt; class
/// &amp;lt;/summary&amp;gt;
public static class HtmlFragmentExtensions
{
&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Writes the XForm to the view context&#39;s output steam.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper instance that this method extends.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;xform&quot;&amp;gt;The XForm to write.&amp;lt;/param&amp;gt;
&#160; &#160; public static void RenderCustomXForm(this HtmlHelper htmlHelper, XForm xform)
&#160; &#160; {
&#160; &#160; &#160; &#160; if (xform == null)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; return;
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; htmlHelper.RenderCustomXForm(xform, new XFormParameters());
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Writes the XForm to the view context&#39;s output steam.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper instance that this method extends.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;xform&quot;&amp;gt;The XForm to write.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;parameters&quot;&amp;gt;The parameters to be used by the XForm.&amp;lt;/param&amp;gt;
&#160; &#160; public static void RenderCustomXForm(this HtmlHelper htmlHelper, XForm xform, XFormParameters parameters)
&#160; &#160; {
&#160; &#160; &#160; &#160; if (xform == null)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; return;
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; htmlHelper.ViewContext.ViewData[&quot;XFormParameters&quot;] = parameters;

&#160; &#160; &#160; &#160; htmlHelper.RenderPartial(typeof(XForm).Name, xform);
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Renders the html fragment.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;fragment&quot;&amp;gt;The fragment.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;renderFragmentsWithoutView&quot;&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; [render fragments without view].&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;returns&amp;gt;A HTML-encoded string.&amp;lt;/returns&amp;gt;
&#160; &#160; public static MvcHtmlString RenderCustomHtmlFragment(this HtmlHelper htmlHelper, HtmlFragment fragment, bool renderFragmentsWithoutView = true)
&#160; &#160; {
&#160; &#160; &#160; &#160; var value = new StringBuilder();

&#160; &#160; &#160; &#160; using (var writer = new StringWriter(value))
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; // Try to find a matching partial view
&#160; &#160; &#160; &#160; &#160; &#160; var viewEngineResult = ViewEngines.Engines.FindPartialView(htmlHelper.ViewContext, fragment.GetType().Name);

&#160; &#160; &#160; &#160; &#160; &#160; if (viewEngineResult.View != null)
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; viewEngineResult.View.Render(viewEngineResult, htmlHelper.ViewContext, writer, fragment);
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; &#160; &#160; else if (renderFragmentsWithoutView)
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // Render fragment directly unless otherwise specified
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; writer.Write(fragment.ToString());
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; return value.Length &amp;lt;= 0 ? MvcHtmlString.Empty : MvcHtmlString.Create(value.ToString());
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Renders the HTML fragment.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;htmlHelper&quot;&amp;gt;The HTML helper.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;fragment&quot;&amp;gt;The fragment.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;partialViewName&quot;&amp;gt;The partial view name.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;useFallback&quot;&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; [use fallback].&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;renderFragmentsWithoutView&quot;&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; [render fragments without view].&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;returns&amp;gt;A HTML-encoded string.&amp;lt;/returns&amp;gt;
&#160; &#160; public static MvcHtmlString RenderCustomHtmlFragment(this HtmlHelper htmlHelper, HtmlFragment fragment, string partialViewName, bool useFallback = true, bool renderFragmentsWithoutView = true)
&#160; &#160; {
&#160; &#160; &#160; &#160; var value = new StringBuilder();

&#160; &#160; &#160; &#160; using (var writer = new StringWriter(value))
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; // Try to find a matching partial view
&#160; &#160; &#160; &#160; &#160; &#160; var viewEngineResult = ViewEngines.Engines.FindPartialView(htmlHelper.ViewContext, partialViewName);

&#160; &#160; &#160; &#160; &#160; &#160; if (viewEngineResult.View != null)
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; viewEngineResult.View.Render(viewEngineResult, htmlHelper.ViewContext, writer, fragment);
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; &#160; &#160; else
&#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // Try to fall back to default view
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (useFallback)
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; return htmlHelper.RenderCustomHtmlFragment(fragment, renderFragmentsWithoutView);
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // Render fragment directly unless otherwise specified
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; if (renderFragmentsWithoutView)
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; writer.Write(fragment.ToString());
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; &#160; &#160; }
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; return value.Length &amp;lt;= 0 ? MvcHtmlString.Empty : MvcHtmlString.Create(value.ToString());
&#160; &#160; }

&#160; &#160; /// &amp;lt;summary&amp;gt;
&#160; &#160; /// Renders the HTML fragment.
&#160; &#160; /// &amp;lt;/summary&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;view&quot;&amp;gt;The view.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;viewEngineResult&quot;&amp;gt;The view engine result.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;context&quot;&amp;gt;The context.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;writer&quot;&amp;gt;The writer.&amp;lt;/param&amp;gt;
&#160; &#160; /// &amp;lt;param name=&quot;fragment&quot;&amp;gt;The fragment.&amp;lt;/param&amp;gt;
&#160; &#160; private static void Render(this IView view, ViewEngineResult viewEngineResult, ViewContext context, TextWriter writer, HtmlFragment fragment)
&#160; &#160; {
&#160; &#160; &#160; &#160; var viewDataDictionaries = new ViewDataDictionary(fragment);

&#160; &#160; &#160; &#160; foreach (var viewDatum in context.ViewData)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; viewDataDictionaries[viewDatum.Key] = viewDatum.Value;
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; var viewContext = new ViewContext(context, viewEngineResult.View, viewDataDictionaries, context.TempData, writer);

&#160; &#160; &#160; &#160; foreach (var modelState in context.ViewData.ModelState)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; viewContext.ViewData.ModelState.Add(modelState.Key, modelState.Value);
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; viewEngineResult.View.Render(viewContext, writer);
&#160; &#160; &#160; &#160; viewEngineResult.ViewEngine.ReleaseView(context.Controller.ControllerContext, viewEngineResult.View);
&#160; &#160; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What this allows us is to override the renderer for XForm in general. We can now use the following code to render an XForm:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(view code taken from&#160;&lt;a href=&quot;#&quot; title=&quot;Using XForms and MVC in an EPiServer 7 Block&quot;&gt;previous blog post about XForms and MVC&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.Web.Mvc.Html
@model EPiServer.Demo.TwitterBootstrap.ViewModels.Partials.XFormBlockViewModel

&amp;lt;div class=&quot;xformpage&quot; @Html.EditAttributes(x =&amp;gt; x.Schema)&amp;gt;
&#160; &#160; @using (Html.BeginXForm(Model.Schema, new { Action = Model.ActionUrl, @class = &quot;form xform&quot; }))
&#160; &#160; {
&#160; &#160; &#160; &#160; Html.RenderCustomXForm(Model.Schema);
&#160; &#160; }
&#160; &#160; &#160; &#160;&#160;
&#160; &#160; if (Model.Schema.Id == ViewData[&quot;XFormID&quot;])
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.ValidationSummary()
&#160; &#160; }
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Right now this just renders the XForm with EPiServers default view, as we haven&#39;t implemented a custom view yet.&lt;br /&gt;Create a file called XForm.cshtml in ~/Views/Shared/DisplayTemplates and insert the following code in it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@using EPiServer.HtmlParsing
@model EPiServer.XForms.XForm

&amp;lt;h3&amp;gt;Custom XForm view&amp;lt;/h3&amp;gt;
@if (Model != null)
{
&#160; &#160; var fragments = Model.CreateHtmlFragments();

&#160; &#160; // Check if this is a postback, and if it is get the posted fragments for this instance
&#160; &#160; if (ViewData[&quot;XFormInstanceID&quot;] != null &amp;amp;&amp;amp; Model.Id == ViewData[&quot;XFormInstanceID&quot;])
&#160; &#160; {
&#160; &#160; &#160; &#160; fragments = (IEnumerable&amp;lt;HtmlFragment&amp;gt;)ViewData[&quot;XFormFragments&quot;];
&#160; &#160; }
&#160; &#160;&#160;
&#160; &#160; // Render all fragments
&#160; &#160; foreach (var fragment in fragments)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.RenderCustomHtmlFragment(fragment, &quot;XForm/&quot; + Model.Id + &quot;/&quot; + fragment.GetType().Name)
&#160; &#160; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you load a page with a XForm on now, you&#39;ll se a header with your xform id above your form.&lt;/p&gt;
&lt;p&gt;Now, lets say we want to utilize some bootstrap styling on our forms. That means we need to get rid of those hideous tables and replace them with our own stuff.&lt;/p&gt;
&lt;p&gt;Replace the RenderCustomHtmlFragment code in the view above with the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@Html.RenderCustomHtmlFragment(fragment, &quot;XForm/&quot; + Model.Id + &quot;/&quot; + fragment.GetType().Name)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code tells our html helper extension to look in the &quot;~/Views/Shared/DisplayTemplates/XForm/{xform-id}/&quot; folder for views for each html fragment.&lt;/p&gt;
&lt;p&gt;Create the following files in the folder mentioned above (replace {xform-id} with the id of your xform):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;InputFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.InputFragment

&amp;lt;div class=&quot;form-group @Model.Reference @Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;label for=&quot;@Model.Reference&quot;&amp;gt;@Model.Label&amp;lt;/label&amp;gt;
&#160; &#160; @if (Model.Required)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextBox(Model.Reference, Server.HtmlDecode(Model.Value) ?? string.Empty, new { @class = &quot;form-control&quot;, size = Model.Size, placeholder = Model.Title, required = &quot;required&quot; })
&#160; &#160; }
&#160; &#160; else
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextBox(Model.Reference, Server.HtmlDecode(Model.Value) ?? string.Empty, new { @class = &quot;form-control&quot;, size = Model.Size, placeholder = Model.Title })
&#160; &#160; }
&#160; &#160; @Html.ValidationMessage(Model.Reference) // EPiServer 7.0 to 7.1
&#160; &#160; @Html.ValidationMessage(Model.ValidationReference) // EPiServer 7.5 and upwards
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ElementFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.HtmlParsing.ElementFragment&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;EndElementFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.HtmlParsing.EndElementFragment&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;SubmitFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.SubmitFragment

&amp;lt;div class=&quot;@Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;input type=&quot;submit&quot; class=&quot;btn btn-default&quot; name=&quot;@Html.Raw(Model.UniqueName)&quot; title=&quot;@Html.Raw(Model.Title)&quot; value=&quot;@Html.Raw(Model.Value)&quot; /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;TextareaFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.TextareaFragment

&amp;lt;div class=&quot;form-group @Model.Reference @Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;label for=&quot;@Model.Reference&quot;&amp;gt;@Model.Label&amp;lt;/label&amp;gt;
&#160; &#160; @if (Model.Required)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextArea(Model.Reference, Model.Value, Model.Rows, Model.Columns, new { @class = &quot;form-control&quot;, placeholder = Model.Title, required = &quot;required&quot; })
&#160; &#160; }
&#160; &#160; else
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.TextArea(Model.Reference, Model.Value, Model.Rows, Model.Columns, new { @class=&quot;form-control&quot;, placeholder = Model.Title })
&#160; &#160; }
&#160; &#160; @Html.ValidationMessage(Model.Reference) // EPiServer 7.0 to 7.1
&#160; &#160; @Html.ValidationMessage(Model.ValidationReference) // EPiServer 7.5 and upwards
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Select1tAsDropdownListFragment.cshtml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;@model EPiServer.XForms.Parsing.Select1Fragment

&amp;lt;div class=&quot;form-group @Model.Reference @Model.Class&quot;&amp;gt;
&#160; &#160; &amp;lt;label for=&quot;@Model.Reference&quot;&amp;gt;@Model.Label&amp;lt;/label&amp;gt;
&#160; &#160; @if (Model.Required)
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.DropDownList(Model.Reference, Model.Options.Select(o =&amp;gt; new SelectListItem() { Text = Server.HtmlDecode(o.Text), Value = Server.HtmlDecode(o.Value), Selected = o.SelectedItem }), new { @class = &quot;form-control&quot;, @title = Model.Title, @required = &quot;required&quot; })
&#160; &#160; }
&#160; &#160; else
&#160; &#160; {
&#160; &#160; &#160; &#160; @Html.DropDownList(Model.Reference, Model.Options.Select(o =&amp;gt; new SelectListItem() { Text = Server.HtmlDecode(o.Text), Value = Server.HtmlDecode(o.Value), Selected = o.SelectedItem }), new { @class = &quot;form-control&quot;, @title = Model.Title })
&#160; &#160; }
&#160; &#160; @Html.ValidationMessage(Model.Reference) // EPiServer 7.0 to 7.1
&#160; &#160; @Html.ValidationMessage(Model.ValidationReference) // EPiServer 7.5 and upwards
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;If you render your form now, you will see that it has very different html output.&lt;br /&gt;This output is also compatible with Twitter Bootstrap and jQuery Validation, meaning you get (partial) client-side validation. Yay! :-)&lt;/p&gt;
&lt;p&gt;All this allows us to go from the following form configuration&lt;br /&gt;&lt;img style=&quot;width: 500px; height: 225.25027808676305px;&quot; src=&quot;http://blob.eyecatch.no/media/1036/form-1.png?width=500&amp;amp;height=225.25027808676305&quot; alt=&quot;&quot; /&gt;&#160;&lt;/p&gt;
&lt;p&gt;And it&#39;s default styling&lt;br /&gt;&lt;img style=&quot;width: 299px; height: 307px;&quot; src=&quot;http://blob.eyecatch.no/media/1037/form_display_before-1.png?width=299&amp;amp;height=307&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To this beautiful form&lt;br /&gt;&lt;img id=&quot;__mcenew&quot; src=&quot;http://blob.eyecatch.no/media/1038/form_display_after-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h3&gt;What more can you do?&#160;&lt;/h3&gt;
&lt;p&gt;You can override the style of all the form fields. Here is a list of file names and models of all field types:&lt;/p&gt;
&lt;table border=&quot;0&quot; class=&quot;mdl-data-table mdl-js-data-table&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;File name&lt;/th&gt;&lt;th&gt;Model&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ElementFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.HtmlParsing.ElementFragment&lt;/td&gt;
&lt;td&gt;Inserted before each &quot;fragment&quot; (row, label, textbox, etc.), and template for horizontal rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EndElementFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.HtmlParsing.EndElementFragment&lt;/td&gt;
&lt;td&gt;Inserted after each &quot;fragment&quot; (row, label, textbox, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;InputFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.InputFragment&lt;/td&gt;
&lt;td&gt;Template for every textbox field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Select1tAsDropdownListFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.Select1Fragment&lt;/td&gt;
&lt;td&gt;Template for every dropdown field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SubmitFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.SubmitFragment&lt;/td&gt;
&lt;td&gt;Template for every submit button&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TextareaFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.TextareaFragment&lt;/td&gt;
&lt;td&gt;Template for every textarea field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TextFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.HtmlParsing.TextFragment&lt;/td&gt;
&lt;td&gt;Template for every heading field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SelectFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.SelectFragment&lt;/td&gt;
&lt;td&gt;Template for every checkbox field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Select1AsRadiobuttonFragment.cshtml&lt;/td&gt;
&lt;td&gt;EPiServer.XForms.Parsing.Select1Fragment&lt;/td&gt;
&lt;td&gt;Template for every radio button field&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;NOTE: You can find the default templates for some of these at &quot;C:\Program Files (x86)\EPiServer\CMS\7.0.586.1\Application\Util\Views\Shared\EditorTemplates&quot;&lt;/em&gt;&lt;/p&gt;</description>            <guid>http://www.eyecatch.no/blog/full-customization-of-xforms-with-episerver-7-and-mvc/</guid>            <pubDate>Wed, 25 Sep 2013 17:52:50 GMT</pubDate>           <category>Blog post</category></item><item> <title>Using XForms and MVC in an EPiServer 7 Block</title>            <link>http://www.eyecatch.no/blog/2013/01/using-xforms-and-mvc-in-an-episerver-7-block/</link>            <description>
&lt;p&gt;The most awesome features of EpiServer 7 is arguably it&#39;s Block
system and that it&#39;s possible to use MVC when developing sites.&lt;/p&gt;

&lt;p&gt;Alas, some things in EPiServer 7 apparently has some bugs when
it comes to supporting MVC and blocks - XForms being one of
them.&lt;/p&gt;

&lt;p&gt;For one thing, XForms requires that you post to a url. That
means you need to post to an instance of a page, or create a
standalone controller for handling xform requests only.&lt;/p&gt;

&lt;p&gt;This blog post will show you how to set up XForms using the
former method.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;First off, you need to create your Block:&lt;/p&gt;

&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;
/// &amp;lt;summary&amp;gt;
/// A xform block
/// &amp;lt;/summary&amp;gt;
[ContentType(DisplayName = &quot;XForm block&quot;)]
public class XFormBlock : BlockData
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;The form&quot;,
        Description = &quot;The form.&quot;,
        GroupName = SystemTabNames.Content,
        Order = 1)]
    [CultureSpecific]
    public virtual XForm Schema { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the post controller.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The post controller.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;Post Controller&quot;,
        Description = &quot;The controller to post the form to.&quot;,
        GroupName = SystemTabNames.Settings,
        Order = 0)]
    public virtual string PostController { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the post action.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The post action.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;Post Action&quot;,
        Description = &quot;The action to run when posting.&quot;,
        GroupName = SystemTabNames.Settings,
        Order = 1)]
    public virtual string PostAction { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the success action.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The success action.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;Success Action&quot;,
        Description = &quot;The action to run on successful post.&quot;,
        GroupName = SystemTabNames.Settings,
        Order = 2)]
    public virtual string SuccessAction { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the failure action.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The failure action.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;Failure Action&quot;,
        Description = &quot;The action to run on post failure.&quot;,
        GroupName = SystemTabNames.Settings,
        Order = 3)]
    public virtual string FailedAction { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the CSS class.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The CSS class.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;CSS class&quot;,
        Description = &quot;The CSS class.&quot;,
        GroupName = SystemTabNames.Settings,
        Order = 5)]
    public virtual string CssClass { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Sets the default values.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;contentType&quot;&amp;gt;Type of the content.&amp;lt;/param&amp;gt;
    public override void SetDefaultValues(ContentType contentType)
    {
        base.SetDefaultValues(contentType);

        this.PostController = string.Empty;
        this.PostAction = &quot;XFormPost&quot;;
        this.SuccessAction = &quot;Index&quot;;
        this.FailedAction = &quot;Index&quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you need to create a controller for showing the XForm on a
page:&lt;/p&gt;

&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;
public class XFormBlockController : BlockController&amp;lt;XFormBlock&amp;gt;
{
    public override ActionResult Index(XFormBlock currentBlock)
    {
        var viewModel = new XFormViewModel(currentBlock);

        if (viewModel.Form != null &amp;amp;&amp;amp; this.PageRouteHelperRepository.Page != null)
        {
            var actionUri = this.PageRouteHelperRepository.Page.GetFriendlyUrl() + currentBlock.PostAction + &quot;/&quot;;
            actionUri = UriSupport.AddQueryString(actionUri, &quot;XFormId&quot;, viewModel.Form.Id.ToString());
            actionUri = UriSupport.AddQueryString(actionUri, &quot;postController&quot;, currentBlock.PostController);
            actionUri = UriSupport.AddQueryString(actionUri, &quot;postAction&quot;, currentBlock.PostAction);
            actionUri = UriSupport.AddQueryString(actionUri, &quot;failedAction&quot;, currentBlock.FailedAction);
            actionUri = UriSupport.AddQueryString(actionUri, &quot;successAction&quot;, currentBlock.SuccessAction);

            viewModel.ActionUri = actionUri;
        }

        var editHints = this.ViewData.GetEditHints&amp;lt;XFormViewModel, XFormBlock&amp;gt;();
        editHints.AddConnection(v =&amp;gt; v.Form, p =&amp;gt; p.Schema);

        return this.PartialView(viewModel);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here is the code for the viewmodel:&lt;/p&gt;

&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;
public class XFormViewModel
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    public XForm Form { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the CSS class.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The CSS class.&amp;lt;/value&amp;gt;
    public string CssClass { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the action URI.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The action URI.&amp;lt;/value&amp;gt;
    public string ActionUri { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You could avoid using a viewmodel like the one above and just
use the block type as a viewmodel, but I like to adhere to the MVVM
model and I want to be able to set a custom css class for an
instance of the block.&lt;/p&gt;

&lt;p&gt;Now we need to create a view for the block. (If you&#39;re using
ReSharper, just ALT+ENTER on the &quot;return
this.PartialView(viewModel)&quot; line)&lt;/p&gt;

&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;
@using EPiServer.Web.Mvc.Html
@model Leroy.Web.EPiServer.ViewModels.Partials.XFormViewModel

&amp;lt;div class=&quot;xformblock @Model.CssClass&quot; @Html.EditAttributes(&quot;Form&quot;)&amp;gt;
    @Html.PropertyFor(x =&amp;gt; x.Form)
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We now have almost everything in place. The block is set up to
post to an action named &quot;XFormPost&quot; on the current page. However,
this action does not exist on a page by default, so we need to
create it somehow.&lt;br /&gt;
 We have accomplished it by creating a base class that all
PageControllers inherit from:&lt;/p&gt;

&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;
/// &amp;lt;summary&amp;gt;
/// The base page controller.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&quot;T&quot;&amp;gt;The page type&amp;lt;/typeparam&amp;gt;
public abstract class BasePageController&amp;lt;T&amp;gt; : PageController&amp;lt;T&amp;gt; where T : PageData
{
    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;xFormpostedData&quot;&amp;gt;The posted xform data.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;The current view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult XFormPost(XFormPostedData xFormpostedData)
    {
        var formData = new XFormPageHelper().GetXFormData(this, xFormpostedData);
        
        var result = XFormActionHelper.DoAction(formData, xFormpostedData, true);

        return this.RedirectToAction(&quot;Index&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is all. Now you just need to add your XFormBlock to a page
using a ContentArea, and the XFormBlockController will take care of
rendering the form. When the user submits the form, the
BasePageController will take care of storing the data and/or
sending emails, etc.&lt;/p&gt;

&lt;p&gt;As you can see on the XFormBlock class, you can specify a custom
action to post to, as well as custom actions to redirect to on
success or failure. This will have to be implemented in the
BasePageController or the controller for your specific Page
Type.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next blog post where I&#39;ll show you how to
completely customize the rendering of the form based on the
built-in MVC rendering engine. :-)&lt;/p&gt;
</description>            <guid>http://www.eyecatch.no/blog/2013/01/using-xforms-and-mvc-in-an-episerver-7-block/</guid>            <pubDate>Mon, 28 Jan 2013 11:01:34 GMT</pubDate>           <category>Blog post</category></item><item> <title>Using XForms and MVC in EPiServer 7</title>            <link>http://www.eyecatch.no/blog/using-xforms-and-mvc-in-episerver-7/</link>            <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: Updated blog post to solve issues and questions posted in the comment section, as well as generalizing it to work with XForm instances on pages as well. This version also supports redirection after form submission as well as proper validation.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The most awesome features of EpiServer 7 is arguably it&#39;s Block system and that it&#39;s possible to use MVC when developing sites.&lt;/p&gt;
&lt;p&gt;Alas, some things in EPiServer 7 apparently has some issues when it comes to supporting MVC - XForms being one of them.&lt;/p&gt;
&lt;p&gt;For one thing, XForms requires that you post to a url. That means you need to post to an instance of a page, or create a standalone controller for handling xform requests only.&lt;/p&gt;
&lt;p&gt;This blog post will show you how to set up XForms using the former method.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;First off, you need to create a base controller that all your pages must derive from:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;public abstract class BasePageController&amp;lt;T&amp;gt; : PageController&amp;lt;T&amp;gt; where T : PageData
{
    /// &amp;lt;summary&amp;gt;
    /// The view data key format
    /// &amp;lt;/summary&amp;gt;
    private const string ViewDataKeyFormat = &quot;TempViewData_{0}&quot;;

    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the &amp;lt;see cref=&quot;BasePageController{T}&quot; /&amp;gt; class.
    /// &amp;lt;/summary&amp;gt;
    protected BasePageController()
    {
        this.ContentId = string.Empty;
    }
    
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the data factory
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The content repository.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public IContentRepository ContentRepository { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the page route helper repository.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The page route helper repository.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public PageRouteHelper PageRouteHelperRepository { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the URL resolver.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The URL resolver.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public UrlResolver UrlResolver { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the xform handler.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The xform handler.&amp;lt;/value&amp;gt;
    [SetterProperty]
    public XFormPageUnknownActionHandler XFormHandler { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the current page.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The current page.&amp;lt;/value&amp;gt;
    public PageData CurrentPage { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets a value indicating whether the block [is in edit mode].
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if the block [is in edit mode]; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.&amp;lt;/returns&amp;gt;
    protected bool IsInEditMode
    {
        get
        {
            return PageEditing.GetPageIsInEditMode(this.HttpContext);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets the view data key.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The view data key.&amp;lt;/value&amp;gt;
    private string ViewDataKey
    {
        get
        {
            return string.Format(ViewDataKeyFormat, this.ContentId);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the content id
    /// &amp;lt;/summary&amp;gt;
    private string ContentId
    {
        get
        {
            return this.TempData[&quot;ContentID&quot;] != null ? this.TempData[&quot;ContentID&quot;].ToString() : (this.TempData[&quot;ContentID&quot;] = string.Empty).ToString();
        }

        set
        {
            this.TempData[&quot;ContentID&quot;] = value;
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;data&quot;&amp;gt;The posted form data.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&quot;contentId&quot;&amp;gt;The block id.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;A view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult XFormPost(XFormPostedData data, string contentId = &quot;&quot;)
    {
        if (!string.IsNullOrEmpty(contentId)) 
        {
            this.ContentId = contentId;
        }

        // Add posted xform instance id to viewdata, so we can retrieve it later
        this.ViewData[&quot;XFormID&quot;] = data.XForm.Id;

        return this.XFormHandler.HandleAction(this);
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback if it was successful.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;data&quot;&amp;gt;The posted form data.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;A view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Success(XFormPostedData data)
    {
        if (data.XForm.PageGuidAfterPost != Guid.Empty)
        {
            var page = this.ContentRepository.Get&amp;lt;PageData&amp;gt;(data.XForm.PageGuidAfterPost);

            return this.Redirect(this.UrlResolver.GetVirtualPath(page.ContentLink, page.LanguageBranch));
        }

        return this.Redirect(this.UrlResolver.GetVirtualPath(this.CurrentPage.ContentLink, this.CurrentPage.LanguageBranch));
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles the XForm postback if it was successful.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;data&quot;&amp;gt;The posted form data.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;A view.&amp;lt;/returns&amp;gt;
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Failed(XFormPostedData data)
    {
        return this.Redirect(this.UrlResolver.GetVirtualPath(this.CurrentPage.ContentLink, this.CurrentPage.LanguageBranch));
    }

    /// &amp;lt;summary&amp;gt;
    /// Called before the action method is invoked.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;filterContext&quot;&amp;gt;Information about the current request and action.&amp;lt;/param&amp;gt;
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Get current page
        this.CurrentPage = this.PageRouteHelperRepository.Page;

        // Set content id if it has not been set
        if (string.IsNullOrEmpty(this.ContentId))
        {
            this.ContentId = this.CurrentPage.PageLink.ID.ToString();
        }

        // Persist view data if this is a failed or successful xform postback, reset if this is a new postback
        if (filterContext.ActionDescriptor.ActionName == &quot;Failed&quot;
            || filterContext.ActionDescriptor.ActionName == &quot;Success&quot;)
        {
            this.TempData[this.ViewDataKey] = this.ViewData;
        }
        else if (filterContext.ActionDescriptor.ActionName == &quot;XFormPost&quot;)
        {
            this.TempData[this.ViewDataKey] = null;
        }
        
        // Merge tempdata into viewdata if it is not null
        var tempData = this.TempData[this.ViewDataKey] as ViewDataDictionary;

        if (tempData != null)
        {
            this.ViewData = tempData;
        }

        base.OnActionExecuting(filterContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h4&gt;Making it work with pages&lt;/h4&gt;
&lt;p&gt;Create a page type class like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ContentType(DisplayName = &quot;XForm Page&quot;)]
public class XFormPage
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;The form&quot;,
        Description = &quot;The form.&quot;,
        GroupName = SystemTabNames.Content,
        Order = 1)]
    [CultureSpecific]
    public virtual XForm Schema { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you need to display the form on the page.&lt;br /&gt;Create a ViewModel class for your page type class:&#160;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;cs&quot;&gt;public class XFormPageViewModel : BasePageViewModel
{
&#160; &#160; public XForm Schema { get; set; }

&#160; &#160; public string ActionUrl { get; set; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then create a page controller that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class XFormPageController : BasePageController&amp;lt;XFormPage&amp;gt;
{
    private readonly UrlResolver urlResolver;

    public XFormPageController(UrlResolver urlResolver)
    {
        this.urlResolver = urlResolver;
    }

    public ActionResult Index(XFormPage currentPage)
    {
        var viewModel = new XFormPageViewModel()
                            {
                                Schema = currentPage.Schema
                            };

        if (currentPage.Schema != null)
        {
            var actionUrl = string.Format(&quot;{0}XFormPost/&quot;, this.urlResolver.GetVirtualPath(currentPage.PageLink, currentPage.LanguageBranch));
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;XFormId&quot;, viewModel.Schema.Id.ToString());
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;failedAction&quot;, &quot;Failed&quot;);
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;successAction&quot;, &quot;Success&quot;);

            viewModel.ActionUrl = actionUrl;
        }

        var editHints = this.ViewData.GetEditHints&amp;lt;XFormPageViewModel, XFormPage&amp;gt;();
        editHints.AddConnection(v =&amp;gt; v.Schema, p =&amp;gt; p.Schema);

        return this.View(viewModel);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could avoid using a viewmodel like the one above and just use the page type as a viewmodel, but I like to adhere to the MVVM model and I want to be able to set a custom css class for an instance of the page.&lt;/p&gt;
&lt;p&gt;Now we need to create a view. (If you&#39;re using ReSharper, just ALT+ENTER on the &quot;return this.View(viewModel)&quot; line)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.Web.Mvc.Html
@model EPiServer.Demo.TwitterBootstrap.ViewModels.Pages.XFormPageViewModel

&amp;lt;div class=&quot;xformpage&quot; @Html.EditAttributes(x =&amp;gt; x.Schema)&amp;gt;
    @using (Html.BeginXForm(Model.Schema, new { Action = Model.ActionUrl, @class = &quot;form xform&quot; }))
    {
        Html.RenderXForm(Model.Schema);
    }
    if (Model.Schema.Id == ViewData[&quot;XFormID&quot;])
    {
        @Html.ValidationSummary()
    }
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note:&#160;Html.ValidationSummary()&#160;is wrapped&#160;in an&#160;if&#160;statement to prevent the validation summary from showing errors from other forms on the same page.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now you&#39;re ready to go. Just create an instance of a XFormPage, add a form to it and try i out.&#160;&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h4&gt;Making it work with Blocks&lt;/h4&gt;
&lt;p&gt;This is very similar to making it work with pages, you just need one more parameter on the action url.&lt;/p&gt;
&lt;p&gt;First off, you need to create your Block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ContentType(DisplayName = &quot;XForm block&quot;)]
public class XFormBlock : BlockData
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    [Display(
        Name = &quot;The form&quot;,
        Description = &quot;The form.&quot;,
        GroupName = SystemTabNames.Content,
        Order = 1)]
    [CultureSpecific]
    public virtual XForm Schema { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the corresponding viewmodel:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class XFormBlockViewModel
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the form.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The form.&amp;lt;/value&amp;gt;
    public XForm Schema { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the action URI.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The action URI.&amp;lt;/value&amp;gt;
    public string ActionUri { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you need to create a controller for showing the block on a page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class XFormBlockController : BlockController&amp;lt;XFormBlock&amp;gt;
{
    private readonly PageRouteHelper pageRouteHelper;

    private readonly UrlResolver urlResolver;

    public XFormBlockController(PageRouteHelper pageRouteHelper, UrlResolver urlResolver)
    {
        this.pageRouteHelper = pageRouteHelper;
        this.urlResolver = urlResolver;
    }

    public override ActionResult Index(XFormBlock currentBlock)
    {
        var id = (currentBlock as IContent).ContentLink.ID;

        // ViewData is not automatically passed to a block controller, need to get it from TempData if it exists
        var viewDataKey = string.Format(&quot;TempViewData_{0}&quot;, id);

        if (this.TempData[viewDataKey] != null)
        {
            this.ViewData = (ViewDataDictionary)this.TempData[viewDataKey];
        }

        // Create the viewmodel
        var viewModel = new XFormBlockViewModel()
                            {
                                Schema = currentBlock.Schema
                            };

        // Create postback url
        if (viewModel.Schema != null &amp;amp;&amp;amp; this.pageRouteHelper.Page != null)
        {
            var actionUrl = string.Format(&quot;{0}XFormPost/&quot;, this.urlResolver.GetVirtualPath(this.pageRouteHelper.Page.PageLink, this.pageRouteHelper.Page.LanguageBranch));
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;XFormId&quot;, viewModel.Schema.Id.ToString());
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;failedAction&quot;, &quot;Failed&quot;);
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;successAction&quot;, &quot;Success&quot;);
            actionUrl = UriSupport.AddQueryString(actionUrl, &quot;contentId&quot;, id.ToString());

            viewModel.ActionUri = actionUrl;
        }

        var editHints = this.ViewData.GetEditHints&amp;lt;XFormBlockViewModel, XFormBlock&amp;gt;();
        editHints.AddConnection(v =&amp;gt; v.Schema, p =&amp;gt; p.Schema);

        return this.PartialView(viewModel);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When that&#39;s done, create the partial view for the block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.Web.Mvc.Html
@model EPiServer.Demo.TwitterBootstrap.ViewModels.Partials.XFormViewModel

&amp;lt;div class=&quot;xformblock&quot; @Html.EditAttributes(x =&amp;gt; x.Schema)&amp;gt;
    @using (Html.BeginXForm(Model.Schema, new { Action = Model.ActionUri, @class = &quot;form xform&quot; }))
    {
        Html.RenderXForm(Model.Schema);
    }
    if (Model.Schema.Id == ViewData[&quot;XFormID&quot;])
    {
        @Html.ValidationSummary()
    }
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE: There is an issue with using the built-in XForm display template and multiple XForm blocks on the same page. Basically, it will replace the contents of all other forms with the content of the posted form on postback.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To solve this, put the following code in a file named XForm.cshtml in a folder called DisplayTemplates in your ~/Views/Shared folder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@using EPiServer.HtmlParsing
@using Leroy.Web.EPiServer.BusinessLogic.Extensions
@model EPiServer.XForms.XForm
           
@if (Model != null)
{
    var fragments = Model.CreateHtmlFragments();

    // Check if this is a postback, and if it is get the posted fragments for this instance
    if (ViewData[&quot;XFormID&quot;] != null &amp;amp;&amp;amp; Model.Id == ViewData[&quot;XFormID&quot;])
    {
        fragments = (IEnumerable&amp;lt;HtmlFragment&amp;gt;)ViewData[&quot;XFormFragments&quot;];
    }
    
    // Render all fragments
    foreach (var fragment in fragments)
    {
        @Html.RenderCustomHtmlFragment(fragment, &quot;XForm/&quot; + Model.Id + &quot;/&quot; + fragment.GetType().Name)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is all. Now you just need to add your XFormBlock to a page using a ContentArea, and the XFormBlockController will take care of rendering the form.&lt;/p&gt;
&lt;p&gt;When the user submits the form, the BasePageController will take care of storing the data and/or sending emails, etc.&lt;/p&gt;
&lt;p&gt;Stay tuned for the next blog post where I&#39;ll show you how to completely customize the rendering of the form based on the built-in MVC rendering engine. :-)&lt;/p&gt;</description>            <guid>http://www.eyecatch.no/blog/using-xforms-and-mvc-in-episerver-7/</guid>            <pubDate>Mon, 28 Jan 2013 11:01:34 GMT</pubDate>           <category>Blog post</category></item><item> <title>Custom Error Pages in EPiServer</title>            <link>http://www.eyecatch.no/blog/custom-error-pages-in-episerver/</link>            <description>&lt;p&gt;Recently, we got a request from a customer to create custom error pages for their EPiServer website. Their requirements were that they should be able to set different error pages for different areas of the website and be able to edit the error page (meaning heading and rich bodytext).&lt;/p&gt;
&lt;p&gt;This may sound straightforward, but it did prove to be a little tricky. EPiServer has it&#39;s own error page handling, and IIS has two different elements for custom error handling (&amp;lt;customErrors /&amp;gt; and &amp;lt;httpErrors /&amp;gt;). In addition, ASP.NET performs a 302 redirect to the error pages specified in &quot;&amp;lt;customErrors /&amp;gt;&quot; which is not good for SEO.&lt;/p&gt;
&lt;p&gt;I.e: If someone links to a page that does not exist on your site, Google would follow that link. If that link then turns into a 302 temporary redirect, Google would put that page (which does not exist) into it&#39;s index. And you don&#39;t want that. It doesn&#39;t matter if it ends up with a 404 status code at the last page, Google still indexes that first page.&lt;/p&gt;
&lt;p&gt;With that in mind, you have at least two ways of rolling your own custom error handling. You can either do everything yourself by hooking into the Application_Error event in global.asax, or try to configure the IIS error handling. In this blog post I will focus on how to do the latter.&lt;/p&gt;
&lt;p&gt;First off, you need to disable the EPiServer error handling. You do that by opening your episerver.config and&#160;setting the &quot;globalErrorHandling&quot; attribute on the &quot;&amp;lt;siteSettings /&amp;gt;&quot; element to &quot;Off&quot;.&lt;/p&gt;
&lt;p&gt;Then you open web.config and&#160;find the&#160;&quot;&amp;lt;customErrors /&amp;gt;&quot; element.&#160;Ensure&#160;that&#160;the &quot;mode&quot; attribute to &quot;RemoteOnly&quot;. (This is&#160;the default mode)&lt;/p&gt;
&lt;p&gt;Now you need to create an error handler that will be the target of all&#160;errors that happen on your site. Create a page named &quot;ErrorHandler.aspx&quot; inside &quot;/Templates/ErrorPages&quot; and make&#160;it derive from EPiServer.TemplatePage.&#160;Add the following code to the class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Handles the Init event of the Page control.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;sender&quot;&amp;gt;The source of the event.&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;e&quot;&amp;gt;The &amp;lt;see cref=&quot;System.EventArgs&quot;/&amp;gt; instance containing the event data.&amp;lt;/param&amp;gt;
protected void Page_Init(object sender, EventArgs e)
{
    var statusCode = this.GetStatusCode(Request.QueryString);
    var originalPage = this.GetOriginalPage(Request.QueryString);

    if (statusCode != 0)
    {
        var errorPage = this.GetErrorPage(originalPage, statusCode);

        if (errorPage != null)
        {
            CurrentPage = errorPage;
        }
    }
}

/// &amp;lt;summary&amp;gt;
/// Gets the HTTP status code from the query string.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;queryString&quot;&amp;gt;The query string.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The HTTP status code&amp;lt;/returns&amp;gt;
private int GetStatusCode(NameValueCollection queryString)
{
    var requestQueryStrings = string.Empty;

    // Try to get query string value in two different ways
    if (queryString.GetKey(0) != null)
    {
        requestQueryStrings = queryString.GetKey(0);
    }
    else if (queryString[0] != null)
    {
        requestQueryStrings = queryString[0];
    }

    if (requestQueryStrings.Split(&#39;;&#39;).Length &amp;gt; 0)
    {
        int code;

        if (int.TryParse(requestQueryStrings.Split(&#39;;&#39;)[0], out code))
        {
            return code;
        }
    }

    return 0;
}

/// &amp;lt;summary&amp;gt;
/// Gets the original page where the error occured.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;queryString&quot;&amp;gt;The query string.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The originating page&amp;lt;/returns&amp;gt;
private PageData GetOriginalPage(NameValueCollection queryString)
{
    int pageId;

    if (int.TryParse(queryString[0], out pageId)) 
    {
        return this.GetPage(new PageReference(pageId));
    }

    return CurrentPage;
}

/// &amp;lt;summary&amp;gt;
/// Gets the correct error page for the specified HTTP status.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;originalPage&quot;&amp;gt;The original page.&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;statusCode&quot;&amp;gt;The status code.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The error page&amp;lt;/returns&amp;gt;
private PageData GetErrorPage(PageData originalPage, int statusCode)
{
    switch (statusCode)
    {
        case 404:
            Response.StatusCode = 404;
            Response.StatusDescription = &quot;Not Found&quot;;
            return this.GetPageFromProperty(originalPage, &quot;ErrorPage404&quot;);
        case 500:
            Response.StatusCode = 500;
            Response.StatusDescription = &quot;Internal Server Error&quot;;
            return this.GetPageFromProperty(originalPage, &quot;ErrorPage500&quot;);
        default:
            Response.StatusCode = 500;
            Response.StatusDescription = &quot;Internal Server Error&quot;;
            return this.GetPageFromProperty(originalPage, &quot;ErrorPage500&quot;);
    }
}

/// &amp;lt;summary&amp;gt;
/// Gets an error page from a page property.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;page&quot;&amp;gt;The page.&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;propertyName&quot;&amp;gt;Name of the property.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;The error page&amp;lt;/returns&amp;gt;
private PageData GetPageFromProperty(PageData page, string propertyName)
{
    var errorPageRef = page[propertyName] as PageReference;

    return !PageReference.IsNullOrEmpty(errorPageRef) ? GetPage(errorPageRef) : null;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you take a closer look, you&#39;ll see that I try to get the error code in two different ways. That is because the 500 error query string and the 404 query strings are a little bit different. There are probably smarter ways to do this, but it solved the problem for me. The strings &quot;ErrorPage500&quot; and &quot;ErrorPage404&quot; are references to Dynamic Properties which we will configure later.&lt;/p&gt;
&lt;p&gt;Now it&#39;s time to set the front end of the ErrorHandler page. This will decide how your error pages will look. I have a very simple page that only shows a heading and some text:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; ErrorPage=&quot;~/Error.htm&quot; CodeBehind=&quot;ErrorHandler.aspx.cs&quot; Inherits=&quot;EyeCatch.EpiServer.CustomErrorPage.Templates.ErrorPages.ErrorHandler&quot; %&amp;gt;
&amp;lt;asp:Content ID=&quot;Content1&quot; ContentPlaceHolderID=&quot;plContent&quot; runat=&quot;server&quot;&amp;gt;
    &amp;lt;h1&amp;gt;&amp;lt;EPiServer:Property ID=&quot;Property1&quot; PropertyName=&quot;Heading&quot; runat=&quot;server&quot; /&amp;gt;&amp;lt;/h1&amp;gt;
    &amp;lt;EPiServer:Property ID=&quot;Property2&quot; PropertyName=&quot;MainBody&quot; runat=&quot;server&quot; /&amp;gt;
&amp;lt;/asp:Content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;EDIT: Added ErrorPage property to the @Page directive, after tip from Tom Pipe in the comments below.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: The only thing you need to copy from the above sample is the &quot;ErrorPage&quot; property in the @Page directive. This is a pointer to a static HTML file that will act as a fallback if EPiServer has problems. The rest of the content of your ErrorHandler.aspx file you can customize yourself.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The ErrorHandler page we&#39;ve just created however, will never&#160;be tied to a Page Type or template. For that we create two&#160;new template pages named &quot;ErrorPage.aspx&quot; and &quot;NotFoundPage.aspx&quot;.&lt;/p&gt;
&lt;p&gt;Add the above HTML to those pages as well (Don&#39;t copy&#160;the codebehind and the @Page directive, this should be left as it is&#160;when you create the file).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;NOTE: The above step is not needed for this to work, but it enables editors to see what the resulting error page looks like. The only thing you need is for&#160;404 and 500&#160;page&#160;types&#160;to have the properties defined in ErrorHandler.aspx&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now go to EPiServer and create a Page Type&#160;that look like this:&lt;/p&gt;
&lt;p&gt;&#160;&lt;img style=&quot;width: 500px; height:265.7430730478589px;&quot; src=&quot;http://blob.eyecatch.no/media/1022/epi_pagetype_settings-1.png?width=500&amp;amp;height=265.7430730478589&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Properties:&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;width: 500px; height:91.70854271356785px;&quot; src=&quot;http://blob.eyecatch.no/media/1023/epi_pagetype_properties-1.png?width=500&amp;amp;height=91.70854271356785&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Do the same for the Not Found page, only exchange &quot;ErrorPage&quot; with &quot;NotFoundPage&quot;.&lt;/p&gt;
&lt;p&gt;Now you need to add some dynamic properties. Click on the &quot;Dynamic Properties&quot; link and then press &quot;Add Property&quot;. Create a property that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;width: 500px; height:270.96370463078847px;&quot; src=&quot;http://blob.eyecatch.no/media/1024/epi_dyn_property-1.png?width=500&amp;amp;height=270.96370463078847&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Do the same for the 500 Error Page, just change &quot;ErrorPage404&quot; to &quot;ErrorPage500&quot; and &quot;404 Error Page&quot; to &quot;500 Error Page&quot;.&lt;/p&gt;
&lt;p&gt;With that done we can go on to create&#160;the actual&#160;error pages and set the dynamic properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create&#160;two pages of type &quot;[Web] ErrorPage&quot; and &quot;[Web] NotFoundPage&quot; somewhere in your site tree. (I created them right under the root node). Fill in the heading and body text (you can also insert an image if you like). Publish the pages.&lt;/li&gt;
&lt;li&gt;Click your root node and then click on the &quot;Dynamic Properties&quot; icon on the toolbar. (The one with 3 blocks on it)&lt;/li&gt;
&lt;li&gt;Set the &quot;404 Not Found Page&quot; and &quot;500 Error Page&quot; properties to the pages you just created. Click &quot;Save&quot;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now it&#39;s time to return to web.config and do the last configuration. You can also perform this step from within IIS Manager, but I&#39;m going to show the web.config way. (The result is the same).&lt;/p&gt;
&lt;p&gt;Insert the following&#160;block at the end of the &quot;&amp;lt;system.webServer /&amp;gt;&quot; block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;httpErrors errorMode=&quot;Custom&quot; existingResponse=&quot;Replace&quot;&amp;gt;
    &amp;lt;remove statusCode=&quot;404&quot; subStatusCode=&quot;-1&quot; /&amp;gt;
    &amp;lt;remove statusCode=&quot;500&quot; subStatusCode=&quot;-1&quot; /&amp;gt;
    &amp;lt;error statusCode=&quot;404&quot; prefixLanguageFilePath=&quot;&quot; path=&quot;/Templates/ErrorPages/ErrorHandler.aspx&quot; responseMode=&quot;ExecuteURL&quot; /&amp;gt;
    &amp;lt;error statusCode=&quot;500&quot; prefixLanguageFilePath=&quot;&quot; path=&quot;/Templates/ErrorPages/ErrorHandler.aspx&quot; responseMode=&quot;ExecuteURL&quot; /&amp;gt;
&amp;lt;/httpErrors&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you&#39;re done!&lt;/p&gt;
&lt;p&gt;If you didn&#39;t understand what you just did, here is a walkthrough:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An error occurs on your site (404 Not Found&#160;or 500 Internal Server Error).&lt;/li&gt;
&lt;li&gt;Since EPiServer is not doing any error handling, the event bubbles up to IIS.&lt;/li&gt;
&lt;li&gt;IIS looks at the &amp;lt;httpErrors /&amp;gt; element and executes the URL that is specified for the HTTP status code.&lt;/li&gt;
&lt;li&gt;It loads &quot;ErrorHandler.aspx&quot; directly (no redirects).&lt;/li&gt;
&lt;li&gt;During the initialization of the ErrorHandler page, it checks what kind of error occured (404 or 500).&lt;/li&gt;
&lt;li&gt;It then gets the page referenced in the Dynamic Property&#160;and loads the&#160;&lt;em&gt;PageData&lt;/em&gt;&#160;for that page (Heading and BodyText).&lt;/li&gt;
&lt;li&gt;ErrorHandler then inserts the Heading and the BodyText into the corresponding elements in the ErrorHandler designer.&lt;/li&gt;
&lt;li&gt;The page is then loaded with your chosen text and with no ugly redirects.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;I hope this tutorial is of use to you. If you have any questions or comments, don&#39;t hestitate to use the comment form below.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;</description>            <guid>http://www.eyecatch.no/blog/custom-error-pages-in-episerver/</guid>            <pubDate>Thu, 08 Sep 2011 18:26:53 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>