Last week we focused on reading RSS and Atom feeds, while this post is all about publishing our own feed. Before you can jump into writing code, you should read up on the different versions of RSS and Atom – especially when you want to use the plain XML approach.
Plain XML to create the feed
As for reading, we can also use plain XML to create our feed. We need to decide what format we want and then regularly check the validator to see if there are problems with what we generate. Then once more, we are on our own and need to specify everything on our own.
We create a MemoryStream, use an XMLWriter and define the metadata of our feed. When this is done, we start the repeating part for each item we want to include in our feed. At the end we flush our writer and return the memory stream:
varoutput=newMemoryStream();using(XmlWriterwriter=XmlWriter.Create(output,newXmlWriterSettings{Indent=true})){writer.WriteStartDocument();writer.WriteStartElement("rss");writer.WriteAttributeString("xmlns","a10",null,"http://www.w3.org/2005/Atom");writer.WriteAttributeString("version","2.0");writer.WriteStartElement("channel");// Feed metadatawriter.WriteElementString("title","My Blog Feed");writer.WriteElementString("link","http://SomeURI");writer.WriteElementString("description","This is a test feed");writer.WriteElementString("language","en-us");// Sample RSS itemwriter.WriteStartElement("item");writer.WriteStartElement("guid");writer.WriteAttributeString("isPermaLink","false");writer.WriteString("ItemThreeID");writer.WriteEndElement();// </guid>writer.WriteElementString("title","#3 - With a Category");writer.WriteElementString("author","C.C@....");writer.WriteElementString("link","http://localhost/Content/three");writer.WriteElementString("description","This is the content for item three");writer.WriteElementString("pubDate",DateTimeOffset.UtcNow.AddHours(-1).ToString("r"));writer.WriteElementString("updated","a10",DateTimeOffset.UtcNow.ToString("r"));writer.WriteElementString("category",".Net");writer.WriteElementString("category","Practice");writer.WriteElementString("category","Work");writer.WriteEndElement();// </item>writer.WriteEndElement();// </channel>writer.WriteEndElement();// </rss>writer.WriteEndDocument();writer.Flush();}returnoutput;
In our Web API we can create an endpoint that calls this method and sends the result out to the client:
A much simpler approach is to use SyndicationFeed to create our feed. Should you not already have installed the package, then you can run this command:
dotnetaddpackageSystem.ServiceModel.Syndication
We can create our feed and specify the metadata in the constructor of the SyndicationFeed class and add more details through the properties it offers. For each post we want to include in our feed, we create a SyndicationItem and add all the relevant data. We then add all the items to a list and hand it to our feed. The final part is to define the feed format by using the appropriate formatter, write it to a MemoryStream and return the result:
// Example from https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-a-basic-rss-feedSyndicationFeedfeed=newSyndicationFeed("My Blog Feed","This is a test feed",newUri("http://SomeURI"));feed.Authors.Add(newSyndicationPerson("[email protected]","Johnny Graber","https://improveandrepeat.com/"));feed.Categories.Add(newSyndicationCategory(".Net"));feed.Description=newTextSyndicationContent("Basic example to produce a RSS feed");feed.ImageUrl=newUri("https://jgraber.ch/images/background.jpg");feed.LastUpdatedTime=DateTimeOffset.Now;SyndicationItemitem3=newSyndicationItem("#3 - With a Category","This is the content for item three",newUri("http://localhost/Content/three"),"ItemThreeID",DateTimeOffset.Now);item3.PublishDate=DateTimeOffset.Now.AddHours(-1);item3.Authors.Add(newSyndicationPerson("C.C@...."));item3.Categories.Add(newSyndicationCategory(".Net"));item3.Categories.Add(newSyndicationCategory("Practice"));item3.Categories.Add(newSyndicationCategory("Work"));List<SyndicationItem>items=newList<SyndicationItem>();items.Add(item3);feed.Items=items;varrssFormatter=newRss20FeedFormatter(feed,true);varoutput=newMemoryStream();varsettings=newXmlWriterSettings{Indent=true,Encoding=Encoding.UTF8};using(varwriter=XmlWriter.Create(output,settings)){rssFormatter.WriteTo(writer);writer.Flush();returnoutput;}
In our Web API we can use a method like this to publish our feed:
While the plain XML approach let us specify the feed exactly as we want it to be, but we must do an awful amount of extra work. It can be done, but I rather spend my time on other things than tracking down XML validation problems.
The SyndicationFeed package does all the heavy lifting for us and we can focus on creating the content for the feed. While we cannot specify every detail, we need a lot less knowledge to create a valid feed.
If I can choose the tool for my projects, I go with the SyndicationFeed package. That way I get a usable abstraction to read feeds and have everything in place should I need to publish one.
I hope this little overview helps you with the creation of your RSS and Atom feeds.