SharePoint: RSS Viewer webpart for WSS 3.0 and SharePoint Foundation 2010

The Out of the box RSS Viewer webpart is not available in free versions of SharePoint like WSS 3.0 and SharePoint Foundation 2010. The code below can be used to mimic the functionality provided by RSS Viewer webpart.
Add a reference to Sytem.ServiceModel dll. It has SyndicationFeed class which is used to read RSS feed. Also the reference to System.Web.Extensions needs to be added in order to use AJAX.

using System;
using System.ComponentModel;
using System.ServiceModel.Syndication;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;

namespace RSSFeedWebPart.RSSFeedWebPart
{
    [ToolboxItemAttribute(false)]
    public class RSSFeedWebPart : WebPart
    {
        UpdatePanel updatePanel;
        Timer timer;
        HtmlTable feedTable;
        private const int const_NumberOfFeedItems = 5;
        private const int const_RereshInterval = 30;
        private int _numberOfFeedItems = const_NumberOfFeedItems;
        private int _rereshInterval = const_RereshInterval;

        [WebBrowsable(true),  
        WebDisplayName("RSS feed url"),
        WebDescription("RSS feed url"),  
        Personalizable(PersonalizationScope.Shared),  
        Category("RSS Feed Custom Properties")]  
        public string RSSFeedUrl { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Show publish date"),
        WebDescription("Show publish date"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public bool IsPublishDate { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Open links in new window"),
        WebDescription("Open links in new window"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public bool IsOpenInNewWindow { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Number of feed items"),
        WebDescription("Number of feed items"),
        Personalizable(PersonalizationScope.Shared),
        DefaultValue(const_NumberOfFeedItems),
        Category("RSS Feed Custom Properties")]
        public int NumberOfItems
        {
            get
            {
                return _numberOfFeedItems;
            }
            set
            {
                _numberOfFeedItems = value;
            }
        }

        [WebBrowsable(true),
        WebDisplayName("Feed refresh time (in minutes)"),
        WebDescription("Feed refresh time (in minutes)"),
        Personalizable(PersonalizationScope.Shared),
        DefaultValue(const_RereshInterval),
        Category("RSS Feed Custom Properties")]
        public int RereshInterval
        {
            get
            {
                return _rereshInterval;
            }
            set
            {
                _rereshInterval = value;
            }
        }

        [WebBrowsable(true),
        WebDisplayName("Feed title style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string FeedTitleStyle { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Item title style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string ItemTitleStyle { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Item publish date style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string ItemPublishDateStyle { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Item summary style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string ItemSummaryStyle { get; set; }

        protected override void CreateChildControls()
        {
            feedTable = new HtmlTable();
            updatePanel = new UpdatePanel();
            updatePanel.ID = "updatePanel";
            timer = new Timer()
            {
                ID = "timer",
                Interval = RereshInterval * 60000,
            };
            timer.Tick += new EventHandler<EventArgs>(timer_Tick);
            this.Controls.Add(timer);
            updatePanel.Triggers.Add(new AsyncPostBackTrigger()
            {
                ControlID = timer.ID,
                EventName = "Tick"
            }
            );
            this.Controls.Add(updatePanel);
            this.Controls.Add(feedTable);                                  
        }

        protected override void OnPreRender(EventArgs e)
        {
            GetFeedData();
        }

        void timer_Tick(object sender, EventArgs e)
        {

        }

        private void GetFeedData()
        {
            try
            {
                feedTable.Border = 0;
                HtmlTableRow htmlrow;
                HtmlTableCell htmlcell;

                if (!string.IsNullOrEmpty(RSSFeedUrl))
                {
                    XmlReader reader = XmlReader.Create(RSSFeedUrl);
                    SyndicationFeed feed = SyndicationFeed.Load(reader);

                    // Add header row in HTML table
                    htmlrow = new HtmlTableRow();
                    htmlcell = new HtmlTableCell();
                    htmlcell.InnerHtml = feed.Title.Text;                    
                    htmlcell.Style.Value = FeedTitleStyle;
                    htmlrow.Cells.Add(htmlcell);
                    feedTable.Rows.Add(htmlrow);
                    int itemCount = 1;
                    foreach (SyndicationItem item in feed.Items)
                    {
                        if (itemCount <= NumberOfItems)
                        {
                            itemCount++;
                            htmlrow = new HtmlTableRow();
                            htmlcell = new HtmlTableCell();                            
                            htmlcell.Style.Value = ItemTitleStyle;
                            if (IsOpenInNewWindow)
                                htmlcell.InnerHtml = "<a href=" + item.Id + "  target=\"_blank\">" + item.Title.Text + "</a>";
                            else
                                htmlcell.InnerHtml = "<a href=" + item.Id + ">" + item.Title.Text + "</a>";  
                            htmlrow.Cells.Add(htmlcell);
                            feedTable.Rows.Add(htmlrow);
                            if (IsPublishDate)
                            {
                                htmlrow = new HtmlTableRow();
                                htmlcell = new HtmlTableCell();
                                htmlcell.InnerHtml = item.PublishDate.ToString();
                                htmlcell.Style.Value = ItemPublishDateStyle;
                                htmlrow.Cells.Add(htmlcell);
                                feedTable.Rows.Add(htmlrow);
                            }
                            htmlrow = new HtmlTableRow();
                            htmlcell = new HtmlTableCell();
                            htmlcell.InnerHtml = ((TextSyndicationContent)item.Summary).Text;
                            htmlcell.Style.Value = ItemSummaryStyle;
                            htmlrow.Cells.Add(htmlcell);
                            feedTable.Rows.Add(htmlrow);                           
                        }
                    }
                }

                updatePanel.ContentTemplateContainer.Controls.Add(feedTable);
            }
            catch (Exception ex)
            {
                // Log exception
            }
        }
    }
}
Following is the snapshot of the Custom properties which are added by the webpart:
Using http://rss.cnn.com/rss/cnn_topstories.rss as the feed Url I get the following results:

profile for Nadeem Yousuf at SharePoint Stack Exchange, Q&A for SharePoint enthusiasts

+