Don’t know what happened to RSS.NET. Looks like it’s trying to go commercial, but still very quiet. Code examples are few and far between (with some simple ones on the site). Also on InformIT.
I’m writing a quick RSS console app (as I lost the last one I wrote!) that I can use to write an RSS feed from a SubVersion hook. Most people use a pre-existing tool for Python (can’t remember the name), but I thought I’d give RSS.NET another go just for kicks.
The example above works fine assuming you’re maintaining state somewhere other than the feed xml file itself. The example also assumes you’re serving this up to the web. You can override the RssFeed.Write() method to take a filename.
If run the same code again (assuming you’ve written to a file) it will simply overwrite it with one item (not add to it). This isn’t what I wanted so…
You need to
- Read the file back in if it’s there – otherwise create
- Add your item to the existing channel if it’s there – otherwise create
- Fix the date behaviour as RSS.NET always assumes UTC dates and appends ‘GMT’. The problem here is that if you’re in Australia (like me) reading and rewriting the same items will effectively add several hours on to existing items every time, because you write the date you read back in for existing items (read and parse into region-specific date, then write back as is). There’s two ways to fix this:
- Before you add your new item – loop through all items and change the item.PubDate to item.PubDate.ToUniversalTime(). This effectively sets it back to the ‘correct’ date.
- Change the RSSWriter class in RSS.NET to convert ToUniversalTime for the Item.PubDate, Channel.PubDate etc. This seems like a better option, but it has potentially more knock on effects in RSS.NET. I’m here to achieve a result, not change the behaviour (possibly adversely) of RSS.NET so I chose option 1
- Before you add your new item – loop through all items and change the item.PubDate to item.PubDate.ToUniversalTime(). This effectively sets it back to the ‘correct’ date.
So here’s the code. Not finished yet and rough around the edges, but works as I need. The intention is to avoid the need for config files and configuring up of feeds specifically. I just want a library function that’s called by a console app. The web serving will simply be based on the location of the file and pointing to some folder in IIS.
string feedURL, string itemTitle, string itemDescription,
DateTime itemPublishDate, string itemURL)
{
bool newFeed = false;
//Try and first open the feed (to see if it’s existing)
RssFeed feed = null;
try
{
feed = RssFeed.Read(feedFileName);
}
catch (FileNotFoundException ex)
{
feed = new RssFeed();
newFeed = true;
}
catch (Exception ex)
{
WriteError(ex);
return;
}
RssChannel channel = null;
//Loop through all channels and if we’ve got the same title reuse
for (int i = 0; i < feed.Channels.Count; i++)
{
if (feed.Channels[i].Title == feedName)
{
channel = feed.Channels[i];
break;
}
}
if (channel == null)
{
channel = new RssChannel();
feed.Channels.Add(channel); //might blow up if already there?
}
RssItem item = new RssItem();
item.Title = itemTitle;
item.Description = itemDescription;
item.PubDate = itemPublishDate.ToUniversalTime();
item.Link = new Uri(itemURL);
//To ensure we don’t screw up existing dates – convert to UTC
foreach (RssItem existingItem in channel.Items)
{
existingItem.PubDate = existingItem.PubDate.ToUniversalTime();
}
//Now add our new item
channel.Items.Add(item);
channel.Title = feedName;
channel.Description = feedDescription;
//channel.LastBuildDate = channel.Items.LatestPubDate();
channel.PubDate = DateTime.UtcNow;
channel.Link = new Uri(feedURL);
feed.Write(feedFileName);
}
Colorized by: CarlosAg.CodeColorizer