Under a timeline, therefore the salient point is "quickly" and willing to throw some $ at it too (not meaning I'll pay the correct answer, but rather for a commercial product :) ).
Looking for an RSS feed generator usuable in .NET framework 2.0. Ideally it would be easy to use (inferred quick) but flexible enough to support the multiple standards (shown part way down this page).
We have the business classes in .NET and want to publish RSS feeds on the ASP.NET website.
Any software that's good?
Doesn't have to be free. Must support .NET framework 2开发者_JAVA百科.0Thanks.
Candidates and Reasoning
- Semweb - appears to be on indefinite hiatus - likely not a good idea to pick up
- ROWLEX - based on Semweb, not fond of using something whose core engine is not being updated
- Linq2Rdf - appears overly complicated for a quick solution
- ASP.NET RSS Toolkit - tried it and appears to generate an old/simplified format - hasn't been touched in a while
Recently I created an RSS feed generator for an ASP.NET application. First, you derive from XmlWriter
. Then you create the page that will host the feeds. There you go:
public enum RssElements
{
Rss, Channel, Title, Description, Link, Copyright, Generator, Item, PubDate
}
public enum RssAttributes
{
Version
}
/// <summary>
/// RSS writer that emits RSS feeds.
/// </summary>
public class RssWriter : XmlWriter
{
private XmlWriter writer;
private Stream objStream;
#region Constructor
public RssWriter (Stream stream)
{
objStream = stream;
writer = XmlWriter.Create (objStream);
}
#endregion
#region Stream Related Operations
public override void Close ()
{
objStream.Close ();
writer.Close ();
}
public override void Flush ()
{
writer.Flush ();
}
#endregion
#region Writing Elements
public void WriteStartElement (RssElements element)
{
string elementName = "";
switch (element)
{
case RssElements.Channel:
elementName = "channel";
break;
case RssElements.Copyright:
elementName = "copyright";
break;
case RssElements.Description:
elementName = "description";
break;
case RssElements.Generator:
elementName = "generator";
break;
case RssElements.Item:
elementName = "item";
break;
case RssElements.Link:
elementName = "link";
break;
case RssElements.PubDate:
elementName = "pubDate";
break;
case RssElements.Rss:
elementName = "rss";
break;
case RssElements.Title:
elementName = "title";
break;
}
writer.WriteStartElement (elementName);
}
public void WriteElementString (RssElements element, string value)
{
string elementName = "";
switch (element)
{
case RssElements.Channel:
elementName = "channel";
break;
case RssElements.Copyright:
elementName = "copyright";
break;
case RssElements.Description:
elementName = "description";
break;
case RssElements.Generator:
elementName = "generator";
break;
case RssElements.Item:
elementName = "item";
break;
case RssElements.Link:
elementName = "link";
break;
case RssElements.PubDate:
elementName = "pubDate";
break;
case RssElements.Rss:
elementName = "rss";
break;
case RssElements.Title:
elementName = "title";
break;
}
writer.WriteElementString (elementName, value);
}
public override void WriteEndElement () { writer.WriteEndElement (); }
#endregion
#region Writing Attributes
public void WriteStartAttribute (RssAttributes attb)
{
if (attb == RssAttributes.Version)
{
writer.WriteStartAttribute ("version");
}
}
public void WriteAttributeString (RssAttributes attb, string value)
{
if (attb == RssAttributes.Version)
{
writer.WriteAttributeString ("version", value);
}
}
public override void WriteEndAttribute () { writer.WriteEndAttribute (); }
#endregion
#region Writing Data
public override void WriteCData (string text) { writer.WriteCData (text); }
public override void WriteChars (char [] buffer, int index, int count) { writer.WriteChars (buffer, index, count); }
public override void WriteComment (string text) { writer.WriteComment (text); }
public override void WriteWhitespace (string ws) { writer.WriteWhitespace (ws); }
public override void WriteString (string text) { writer.WriteString (text); }
#endregion
#region Document
public override void WriteStartDocument () { writer.WriteStartDocument (); }
public override void WriteStartDocument (bool standalone) { writer.WriteStartDocument (standalone); }
public override void WriteEndDocument () { writer.WriteEndDocument (); }
#endregion
#region Not Implemented Methods
void ThrowException () { throw new Exception ("The method or operation is not implemented."); }
public override string LookupPrefix (string ns) { ThrowException (); return ""; }
public override void WriteBase64 (byte [] buffer, int index, int count) { ThrowException (); }
public override void WriteCharEntity (char ch) { ThrowException (); }
public override void WriteStartElement (string prefix, string localName, string ns) { ThrowException (); }
public override WriteState WriteState
{
get { throw new Exception ("The method or operation is not implemented."); }
}
public override void WriteSurrogateCharEntity (char lowChar, char highChar) { ThrowException (); }
public override void WriteEntityRef (string name) { ThrowException (); }
public override void WriteFullEndElement () { ThrowException (); }
public override void WriteProcessingInstruction (string name, string text) { ThrowException (); }
public override void WriteRaw (string data) { ThrowException (); }
public override void WriteRaw (char [] buffer, int index, int count) { ThrowException (); }
public override void WriteStartAttribute (string prefix, string localName, string ns) { ThrowException (); }
public override void WriteDocType (string name, string pubid, string sysid, string subset) { ThrowException (); }
#endregion
}
Then you create the host page. It's an empty page; all the work is done in the Page_Load event. Below I give you the Page_Load event. Note: you can replace the database objects with your business objects.
protected void Page_Load (object sender, EventArgs e)
{
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "text/xml";
RssWriter writer = new RssWriter (Response.OutputStream);
writer.WriteStartElement (RssElements.Rss);
writer.WriteAttributeString (RssAttributes.Version, "2.0");
writer.WriteStartElement (RssElements.Channel);
writer.WriteElementString (RssElements.Title, "XYZ corp.com");
writer.WriteElementString (RssElements.Link, "http://www.yourdomain.com");
writer.WriteElementString (RssElements.Description, "Latest news from XYZ corp");
writer.WriteElementString (RssElements.Copyright, "Copyright (C) XYZ corp. All rights reserved.");
writer.WriteElementString (RssElements.Generator, "XYZ corp XML RSS Generator");
DataTable newsTable = NewsAccess.GetLatestNewsByDate (false);
if (newsTable.Rows.Count > 0) {
for (int i = 0; i < newsTable.Rows.Count; ++i)
{
string id = newsTable.Rows [i] ["LatestNewsID"].ToString ();
string subject = newsTable.Rows [i] ["Subject"].ToString ();
string description = newsTable.Rows [i] ["Description"].ToString ();
bool publicView = newsTable.Rows [i] ["PublicView"].ToString () == "True" ? true : false;
if (!publicView)
continue;
//string details = newsTable.Rows [i] ["Details"].ToString ();
DateTime dt = DateTime.Parse (newsTable.Rows [i] ["DateCreated"].ToString ());
string date = dt.ToString ("R");
writer.WriteStartElement (RssElements.Item);
writer.WriteElementString (RssElements.Title, subject);
writer.WriteElementString (RssElements.Link, "http://www.yourdomain.com/Contents/News/newsarticle.aspx?id=" + id.ToString ());
writer.WriteElementString (RssElements.Description, description);
writer.WriteElementString (RssElements.PubDate, date);
writer.WriteEndElement ();
}
}
writer.WriteEndElement ();
writer.WriteEndElement ();
writer.Close ();
Response.End ();
}
I hope it helped a bit.
here's some vb.net code that I've used to generate a rss feed from a collection in our BLL:
Dim xws As New XmlWriterSettings()
xws.Encoding = Encoding.UTF8
Using xw As XmlWriter = XmlTextWriter.Create(XmlFileName, xws)
xw.WriteStartDocument()
xw.WriteStartElement("rss")
xw.WriteAttributeString("version", "2.0")
xw.WriteStartElement("channel")
xw.WriteElementString("title", Title)
xw.WriteElementString("link", Link)
xw.WriteElementString("description", Description)
xw.WriteElementString("managingEditor", Editor)
Dim items As System.Collections.Generic.List(Of FolderDocuments) = FolderDocuments.GetFolderDocuments()
If items IsNot Nothing Then
For Each fd As FolderDocuments In items
xw.WriteStartElement("item")
xw.WriteElementString("title", fd.Title)
xw.WriteElementString("description", fd.Intro)
xw.WriteElementString("link", fd.Url)
xw.WriteElementString("pubDate", fd.DateStart.ToString("R"))
xw.WriteEndElement()
Next
Else
xw.WriteStartElement("item")
xw.WriteEndElement()
End If
xw.WriteEndElement()
xw.WriteEndElement()
xw.WriteEndDocument()
End Using
This writes to a file, but you could easily use a generic handler (.ashx) to pass parameters to that would generate the required rss feed on the fly - use Response.Output for the xml writer.
精彩评论