I converted some code from a Web Form project that was using the XmlTextWriter class to generate RSS. 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 had been 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;
            }
        }
    }
}

Please share your ideas!

Added Wednesday 23 December 2009 12:37 — Tags for this page: ASP.NET, MVC, Development

Comments

  1. CW Tuesday 29 December 2009 14:30

    http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.aspx

  2. Author Comment 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 to keep the old code since it did exactly what was needed. Microsoft's poor track record of following web standards also made me a bit skeptical.

Add Your Comment