Created
June 15, 2011 14:08
-
-
Save davidwhitney/1027181 to your computer and use it in GitHub Desktop.
Rss feed formatter ActionResult for ASP.NET MVC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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