How to Create an RSS Feed in EPiServer (ASP.NET MVC)

Thanks to Ted and a guy from CodeInside for your blogs which helped come up with this solution.

Problem: Create an RSS feed for ASP.NET MVC Website with EPiServer

Solution: We need three things

1. RssResult class
2. RssPage page type
3. RssPageController which creates the xml rss feed

So let’s begin with the RssResult class. This class needs to inherit FileResult (System.Web.Mvc) passing rss+xml as content type.

 public class RssResult : FileResult  
{
private readonly SyndicationFeed _feed;
public RssResult(SyndicationFeed feed)
: base("application/rss+xml")
{
_feed = feed;
}
public RssResult(string title, List<SyndicationItem> feedItems)
: base("application/rss+xml")
{
_feed = new SyndicationFeed(title, title, HttpContext.Current.Request.Url) { Items = feedItems };
}
protected override void WriteFile(HttpResponseBase response)
{
using (XmlWriter writer = XmlWriter.Create(response.OutputStream))
{
_feed.GetRss20Formatter().WriteTo(writer);
}
}
}

Then, we create a model page type which I’ve named RssPage.cs. It basically only has one property which holds the root page of the RSS

 [ContentType(  
DisplayName = "Rss Page",
GUID = "2ba86356-847f-439f-bf1c-36f7cf70158e",
Description = "Used to create an RSS Feed")]
public class RssPage : SitePageData
{
[Display(
Name = "RSS Root Page",
GroupName = SystemTabNames.Content,
Order = 10)]
[Required]
public virtual PageReference RssPageLink { get; set; }
public PageDataCollection GetPages()
{
var pages = DataFactory.Instance.GetChildren(RssPageLink);
return FilterForVisitor.Filter(pages);
}
}

Now we create the controller for this page type.

 public class RssPageController : PageControllerBase<RssPage>  
{
public ActionResult Index(RssPage currentPage)
{
return Feed(currentPage);
}
public virtual ActionResult Feed(RssPage currentPage)
{
var items = new List<SyndicationItem>();
var newsPages = DataFactory.Instance.GetChildren<NewsPage>(currentPage.RssPageLink);
var pageUri = currentPage.RssPageLink.GetUri();
foreach(var newsPage in newsPages)
{
var feedPackageItem = new SyndicationItem(newsPage.PageTitle, newsPage.Description, pageUri);
feedPackageItem.PublishDate = newsPage.StartPublish;
items.Add(feedPackageItem);
}
return new RssResult("My News Feed", items);
}
}

Now we create an instance of this page on EPiServer.

Navigating to this page now shows an xml rss page

Any questions, please comment!

Using XForms in EPiServer 8 MVC

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

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

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

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

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

The view is short and simple:

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

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

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

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

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

And finally the View:

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

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

Or you can also create a new one if needed.