How do I make an RSS feed in Episerver?
- Page Owner: Not Set
- Last Reviewed: 2020-06-16
How do I make an RSS feed in Episerver?
Answer
Here's the RSS Feed Page from Calamos
RSSPageController.cs:
using Blend.Episerver;
using BlendInteractive.EPiServerSolr;
using Calamos.Base.Business.Solr;
using Calamos.Base.Controllers;
using Calamos.CalamosInvestments.Models.Pages;
using Calamos.CalamosInvestments.Models.Pages.ViewModels;
using EPiServer.Framework.DataAnnotations;
using EPiServer.Web.Mvc;
using SolrNet;
using System;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Xml;
using System.Xml.Linq;
namespace Calamos.CalamosInvestments.Controllers.Pages
{
[TemplateDescriptor(AvailableWithoutTag = false, ModelType = typeof(BlogPage), Tags = new[] { "RSS" })]
public class RssBlogPageController : PageController<BlogPage>
{
public RssBlogPageController()
{
}
public RssActionResult Index(BlogPage currentPage)
{
var model = new BlogPageViewModel(currentPage);
var query = this.DefaultSolrSearch(model);
if (currentPage.FeaturedPostContentArea.HasValue())
query.ExcludeIds(currentPage.FeaturedPostContentArea.AsContent<BlogPostPage>().Select(x => x.ContentLink));
var searchResults = query.Search().Results.GetContentResult<SearchDocument, BlogPostPage>();
var feed = CreateValidFeed(currentPage.Name, currentPage.GetFriendlyUrl(GetFriendlyUrlOption.UseSiteDefinitionHost | GetFriendlyUrlOption.IncludeHost), currentPage.Summary);
feed.Items = searchResults.Select(ConvertToSyndicationItem);
return new RssActionResult() { Feed = feed };
}
private IEPiServerSolrSearch<SearchDocument> DefaultSolrSearch(BlogPageViewModel model)
{
var query = new EPiServerSolrSearch<SearchDocument>()
.IncludeContentTypeExact(typeof(BlogPostPage).Name)
.AddFacetField(x => x.BlogCategories)
.AddFacetField(x => x.BlogVerticals)
.AddFacetField(x => x.BlogTags)
.AddFacetField(x => x.Authors)
.AddFilterForContentBranch(model.CurrentPage.ContentLink)
.SortBy(x => x.PublicDate, Order.DESC)
.PageIndex(1)
.PageWeight(50);
return query;
}
private SyndicationItem ConvertToSyndicationItem(BlogPostPage item)
{
return new SyndicationItem
{
Title = new TextSyndicationContent(item.Name),
Id = item.GetFriendlyUrl(GetFriendlyUrlOption.UseSiteDefinitionHost),
Content = new TextSyndicationContent(item.Summary),
BaseUri = new Uri(item.GetFriendlyUrl(GetFriendlyUrlOption.UseSiteDefinitionHost)),
PublishDate = item.StartPublish.Value
};
}
private SyndicationFeed CreateValidFeed(string title, string url, string description)
{
var uri = new Uri(url);
var feed = new SyndicationFeed()
{
Title = new TextSyndicationContent(title),
Description = new TextSyndicationContent(description),
BaseUri = uri,
LastUpdatedTime = DateTime.Now,
Language = "en-us",
};
XNamespace atom = "http://www.w3.org/2005/Atom";
feed.AttributeExtensions.Add(new XmlQualifiedName("atom", XNamespace.Xmlns.NamespaceName), atom.NamespaceName);
feed.ElementExtensions.Add(new XElement(atom + "link", new XAttribute("href", url), new XAttribute("rel", "self"), new XAttribute("type", "application/rss+xml")));
feed.Links.Add(new SyndicationLink(uri, "alternate", "Link Title", "text/html", 1000));
var formatter = feed.GetRss20Formatter();
formatter.SerializeExtensionsAsAtom = false;
return formatter.Feed;
}
}
}
RssActionResult.cs
using System.ServiceModel.Syndication;
using System.Text;
using System.Web.Mvc;
using System.Xml;
namespace Apta.Base.Model
{
public class RssActionResult : ActionResult
{
public SyndicationFeed Feed { get; set; }
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Clear();
context.HttpContext.Response.ContentEncoding = Encoding.UTF8;
context.HttpContext.Response.ContentType = "text/xml";
Rss20FeedFormatter rssFormatter = new Rss20FeedFormatter(Feed);
using (var writer = XmlWriter.Create(context.HttpContext.Response.Output))
{
rssFormatter.WriteTo(writer);
}
}
}
}
Additional Posts
I solved this problem a few years back.
https://gitlab.blendinteractive.com/deane/RssFactory
RssFactory is just a generic RSS feed. EpiserverRssFactory wraps that for Episerver content.
Something like:
var rssFactory = new EpiserverRssFactory()
{
Title = "whatever",
TitleProperty = "PageName",
SummaryProperty = "MainBody",
// more properties here
};
rssFactory.Pages = myPages; // It's an IList<PageData>
var rss = rssFactory.GetRss();