借助.NET Framework 3.5与ASP.NET MVC框架的支持,在新版本.NET Framework上实现简单的内容发布的RSS是非常容易的。主要完成以下两步工作即可(附代码示例):
1. 生成要发布的内容,在.NET 3.5中可以使用 SyndicationItem 类表示一条RSS记录,使用 SyndicationFeed 类来表示并最终生成RSS。这两个类位于 System.ServiceModel.Syndication 命名空间下,支持生成Atom1.0与Rss2.0两种格式的内容。第一步我们来生成 SyndicationItem 的列表:
首先由数据库查询我们要发布的内容:
1 var newsObj = DContext.News.OrderByDescending(r => r.ID).Take(num).ToList();
这里使用了Linq to SQL,代码很简单不做解释。接下来生成Rss实体的列表:
List<SyndicationItem> ret = new List<SyndicationItem>(); foreach (var r in newsObj) { var synObj = new SyndicationItem(); synObj.Title = TextSyndicationContent.CreatePlaintextContent(r.Title); synObj.Summary = TextSyndicationContent.CreatePlaintextContent(r.Summary); synObj.Content = TextSyndicationContent.CreatePlaintextContent(r.Summary); synObj.Links.Add(new SyndicationLink(new Uri("http://yourhost/news/newsitem/" + r.ID))); synObj.PublishDate = new DateTimeOffset(r.Postdate); ret.Add(synObj); }
这个对象下一步将作为 SyndicationFeed 类构造函数的参数来构建一个 SyndicationFeed 对象。相关代码会在后文一并展示。
为了将生成的RSS发布出去,我们实现一个自定义的ActionResult类 – RssResult 。这个类中最重要的一个方法就是重写的基类的 ExecuteResult 方法,其最终将Rss写入到输出流中,闲言少叙直接给出代码:
1 public class RssResult : ActionResult 2 { 3 private string _title; 4 private string _desc; 5 private Uri _altLink; 6 private List<SyndicationItem> _items; 7 8 public RssResult(string title, string desc, string link, List<SyndicationItem> items) 9 { 10 _title = title; 11 _desc = desc; 12 _altLink = new Uri(link); 13 _items = items; 14 } 15 16 public override void ExecuteResult(ControllerContext context) 17 { 18 SyndicationFeed rss = new SyndicationFeed( 19 _title, 20 _desc, 21 _altLink, 22 _items 23 ); 24 25 XmlWriterSettings settings = new XmlWriterSettings(); 26 settings.Indent = true; 27 settings.NewLineHandling = NewLineHandling.Entitize; 28 29 using (XmlWriter _writer = XmlWriter.Create(context.HttpContext.Response.OutputStream, settings)) 30 { 31 rss.SaveAsAtom10(_writer); 32 } 33 } 34 }
通过上面简单的几步我们就完成了Rss的发布。
后续
完成了发布,我们在来了解一下如何很轻松的在Silverlight中实现Rss的获取与显示,当然这也多亏Silverlight Framework中提供的与.NET Framework中一致的SyndicatedFeed类。首先我们需要获取到Rss的Xml内容,出于安全考虑Silverlight默认不允许跨域访问其它服务器,但往往我们需要的如Rss内容不会与Silverlight运行的机子处于一个域中,这种情况下Silverlight会查找服务器上名为Crossdomain.xml的文件,如果找到则会解析其中的规则,如果Silverlight被允许跨域则可以访问内容,否则会抛出异常。下面的代码中,我们首先使用Silverlight Framework中的 WebClient的OpenReadAsync方法得到xml。
1 public Page() 2 { 3 InitializeComponent(); 4 WebClient client = new WebClient(); 5 Uri uri = new Uri("http://localhost:36360/rss", UriKind.Absolute); 6 client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted); 7 client.OpenReadAsync(uri); 8 }
对于这个异步请求,我们需要在回调函数中进行处理,我们使用SyndicatedFeed解析(反序列化)Rss内容,并将其绑定到控件上,下面代码的前一部分是我们绑定目标 – ItemControl的XAML:
1 <ItemsControl x:Name="_itemTitles"> 2 <ItemsControl.ItemTemplate> 3 <DataTemplate> 4 <StackPanel Orientation="Vertical"> 5 <TextBlock FontWeight="Bold" Text="{Binding Title.Text}" /> 6 </StackPanel> 7 </DataTemplate> 8 </ItemsControl.ItemTemplate> 9 </ItemsControl>
接着是回调函数:
1 void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 2 { 3 XmlReader r = XmlReader.Create(e.Result); 4 SyndicationFeed feed = SyndicationFeed.Load(r); 5 _itemTitles.ItemsSource = feed.Items; 6 }
代码中粗体部分是与绑定相关的属性。这样我们就在Silverlight中把Rss源的标题以列表形式展示了出来。