Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Created June 15, 2011 14:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidwhitney/1027181 to your computer and use it in GitHub Desktop.
Save davidwhitney/1027181 to your computer and use it in GitHub Desktop.
Rss feed formatter ActionResult for ASP.NET MVC
using System;
using System.IO;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Text;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Linq;
public abstract class SyndicationFeedResult<TFeedFormatter> : ActionResult where TFeedFormatter : SyndicationFeedFormatter
{
public SyndicationFeed Feed { get; set; }
protected TFeedFormatter Formatter;
protected XmlWriterSettings WriterSettings;
protected SyndicationFeedResult(SyndicationFeed feed)
{
Feed = feed;
}
public abstract TFeedFormatter ConstructFeedFormatter();
public abstract XmlWriterSettings ConfigureXmlWriter();
public abstract string ConfigureOutputContentType();
public abstract void PostProcessOutputBuffer(StringBuilder buffer);
public override void ExecuteResult(ControllerContext context)
{
Formatter = ConstructFeedFormatter();
WriterSettings = ConfigureXmlWriter();
context.HttpContext.Response.ContentType = ConfigureOutputContentType();
var buffer = new StringBuilder();
var cachedOutput = new StringWriter(buffer);
using (var writer = XmlWriter.Create(cachedOutput, WriterSettings))
{
if (writer != null)
{
Formatter.WriteTo(writer);
writer.Close();
}
}
PostProcessOutputBuffer(buffer);
context.HttpContext.Response.Output.Write(buffer.ToString());
}
}
public class RssResult : SyndicationFeedResult<Rss20FeedFormatter>
{
public RssResult(SyndicationFeed feed)
: base(feed)
{
}
public override Rss20FeedFormatter ConstructFeedFormatter()
{
return new Rss20FeedFormatter(Feed);
}
public override XmlWriterSettings ConfigureXmlWriter()
{
return new XmlWriterSettings
{
NewLineHandling = NewLineHandling.None,
Indent = true,
Encoding = Encoding.UTF32,
ConformanceLevel = ConformanceLevel.Document,
OmitXmlDeclaration = true
};
}
public override string ConfigureOutputContentType()
{
return "application/xml";
}
public override void PostProcessOutputBuffer(StringBuilder buffer)
{
var xmlDoc = XDocument.Parse(buffer.ToString());
foreach (var element in xmlDoc.Descendants("channel").First().Descendants("item").Descendants("description"))
{
VerifyCdataHtmlEncoding(buffer, element);
}
foreach (var element in xmlDoc.Descendants("channel").First().Descendants("description"))
{
VerifyCdataHtmlEncoding(buffer, element);
}
buffer.Replace(" xmlns:a10=\"http://www.w3.org/2005/Atom\"", " xmlns:atom=\"http://www.w3.org/2005/Atom\"");
buffer.Replace("a10:", "atom:");
}
private static void VerifyCdataHtmlEncoding(StringBuilder buffer, XElement element)
{
if (!element.Value.Contains("<") || !element.Value.Contains(">"))
{
return;
}
var cdataValue = string.Format("<{0}><![CDATA[{1}]]></{2}>", element.Name, element.Value, element.Name);
buffer.Replace(element.ToString(), cdataValue);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment