
I like to use the XmlTextWriter class to generate RSS with complete control. Here's what I ended up with to get it working from a Controller in a ASP.NET MVC 1.0 project.
Outside of MVC I've been used to putting the XmlTextWriter in the response like this:
Response.Clear(); Response.ContentType = "text/xml"; Response.Charset = "utf-8"; XmlTextWriter xtw = new XmlTextWriter(Response.OutputStream, Encoding.UTF8); ... xtw.Flush(); xtw.Close(); Response.End();
With MVC I thought it would be nicer to use use an ActionResult:
public ActionResult Index()
{
StringWriterWithEncoding writer = new StringWriterWithEncoding(Encoding.UTF8);
XmlTextWriter xtw = new XmlTextWriter(writer);
xtw.Formatting = Formatting.Indented;
xtw.WriteStartDocument();
xtw.WriteStartElement("rss");
xtw.WriteAttributeString("version", "2.0");
xtw.WriteAttributeString("xmlns:atom", "http://www.w3.org/2005/Atom");
xtw.WriteStartElement("channel");
xtw.WriteElementString("title", "X");
xtw.WriteElementString("link", "http://x.com/");
xtw.WriteStartElement("atom:link");
xtw.WriteAttributeString("href", "http://x.com/feed/");
xtw.WriteAttributeString("rel", "self");
xtw.WriteAttributeString("type", "application/rss+xml");
xtw.WriteEndElement();
xtw.WriteElementString("description", "The latest x.");
xtw.WriteElementString("language", "en-US");
xtw.WriteElementString("lastBuildDate", DateTime.Now.ToUniversalTime().ToString("r"));
xtw.WriteElementString("pubDate", x.ToUniversalTime().ToString("r"));
xtw.WriteElementString("copyright", "Johan Kronberg");
xtw.WriteElementString("ttl", "5");
// Loop something
xtw.WriteStartElement("item");
xtw.WriteElementString("title", "item-x");
xtw.WriteStartElement("description");
xtw.WriteCData("<p>x</p>");
xtw.WriteEndElement();
string linkToItem = "http://x.com/x/";
xtw.WriteElementString("link", linkToItem);
xtw.WriteElementString("guid", linkToItem);
xtw.WriteElementString("pubDate", loopItem.CreatedOn.ToUniversalTime().ToString("r"));
xtw.WriteEndElement();
xtw.WriteEndElement();
xtw.WriteEndElement();
xtw.WriteEndDocument();
xtw.Flush();
xtw.Close();
return Content(writer.ToString(), "text/xml", Encoding.UTF8);
}
To avoid getting the UTF-16 encoding in the document specification I followed this post and comments at Robert McLaws' and ended up with the following copied class:
namespace Krompaco
{
using System;
using System.IO;
using System.Text;
public class StringWriterWithEncoding : StringWriter
{
private Encoding _enc;
public StringWriterWithEncoding(Encoding NewEncoding) : base()
{
_enc = NewEncoding;
}
public override System.Text.Encoding Encoding
{
get
{
return _enc;
}
}
}
}
Not perfect but good enough I hope. Please share your ideas!
Categories: ASP.NET MVC, Dotnet, Development
Last update Wednesday 23 December 2009 12:37
RSS for comments to this page Trackback URL
Comment from CW Tuesday 29 December 2009 14:30
http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.aspx
Comment from Author Tuesday 29 December 2009 15:05
Thank you for commenting CW. I looked into that namespace, and found a few other blog posts using it with MVC, but I wanted more control. Microsoft's poor track record of following web standards also made me skeptical.