ASP.NET MVC 中的 RSS 源

Posted

技术标签:

【中文标题】ASP.NET MVC 中的 RSS 源【英文标题】:RSS Feeds in ASP.NET MVC 【发布时间】:2010-09-05 22:19:34 【问题描述】:

您建议如何在 ASP.NET MVC 中处理 RSS 源?使用第三方库?在 BCL 中使用 RSS 的东西?只是制作一个呈现 XML 的 RSS 视图?还是完全不同的东西?

【问题讨论】:

使用 RssToolkit,您只需要在项目中有一个 .ashx 文件即可生成 RSS 提要。然后,您可以将其 URL 重写为友好的 URL。我认为这种方法没有任何反对 MVC 的地方。 这是一个后续帖子,它通过广义 SyndicationAction 结果类和 304 NotModified 条件获取过滤器进一步提升了 RssActionResult 的想法。 58bits.com/blog/… 我写了一个 RssResult,如果你喜欢可以看看。它应该满足您的要求http://www.wduffy.co.uk/blog/rs-s-result-aspnet-mvc-rss-actionresult/ 只是在上次编辑后的 ​​18 个月内更新这个问题 - 质疑“随着 .net 和 mvc 的迭代而改变的事情会改变我们处理提要管理问题的方式”似乎是合理的?共识(通过不同的 SO 线程)是,“没有根本性的变化——这仍然是你最好的选择。” 对 ASP.NET MVC 的不好建议。 【参考方案1】:

这是我的建议:

    创建一个名为 RssResult 的类 继承抽象基类 行动结果。 重写 ExecuteResult 方法。 ExecuteResult 具有由调用者传递给它的 ControllerContext,您可以通过它获取数据和内容类型。

    将内容类型更改为 rss 后,您需要将数据序列化为 RSS(使用您自己的代码或其他库)并写入响应。

    在要返回 rss 的控制器上创建一个操作,并将返回类型设置为 RssResult。根据您想要返回的内容从模型中获取数据。

    那么对这个动作的任何请求都会收到你选择的任何数据的 rss。

这可能是在 ASP.NET MVC 中返回 rss 以响应请求的最快且可重用的方式。

【讨论】:

Hanselman 有一个similar solution(视频:从 41m 左右开始),他继承自 FileResult。通过这样做,您可以让您的类的构造函数调用base("application/rss+xml") 并避免步骤 3 和 4。他确实覆盖了 ExecuteResult,但这并不重要。他还简化了许多典型的 homespun 代码,并使用了 SyndicateItemSyndicateFeedRss20FeedFormatter 的 3.5+ 功能。 @Dale:当您想要输出以馈送到部分视图时,是否可以写入响应?谢谢。 更新了我之前评论中Hanselman's video 的链接。【参考方案2】:

另一种疯狂但有其优势的方法是使用普通的 .aspx 视图来呈现 RSS。在您的操作方法中,只需设置适当的内容类型。这种方法的一个好处是很容易理解正在渲染的内容以及如何添加自定义元素,例如地理位置。

再一次,列出的其他方法可能更好,我只是没有使用它们。 ;)

【讨论】:

@Haacked:世界上到处都是模板系统生成的无效 RSS XML。请不要添乱!瑞奇,html 编码!= XML 编码。 以下是 MSDN 的 Html Encode 文档: > 由于当前的实现细节,该函数可以用作 xmlEncode 函数。目前,该函数使用的所有命名实体也是xml预定义的命名实体。它们是 " & 编码为 < > " 和 &。其他实体是十进制编码的,如  。http://msdn.microsoft.com/en-us/library/73z22y6h.aspx 如何确保 XML 以这种方式有效?如果视图渲染与传入的 Web 请求分离,以使 XML 视图或电子邮件模板(如 done ruby​​ on rails)成为可能,那就太好了。 您可以创建一个派生自 ActionResult 的 RssResult,而不是使用视图引擎。我们使用将对象序列化为 JSON 的 JsonResult 来执行此操作。在您的情况下,您会发现一些序列化程序(我认为 WCF 有一个)可以序列化为 RSS。【参考方案3】:

我同意 Haacked 的观点。我目前正在使用 MVC 框架实现我的网站/博客,并采用了为 RSS 创建新视图的简单方法:

<%@ Page ContentType="application/rss+xml" Language="C#" AutoEventWireup="true" CodeBehind="PostRSS.aspx.cs" Inherits="rr.web.Views.Blog.PostRSS" %><?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>ricky rosario's blog</title>
<link>http://<%= Request.Url.Host %></link>
<description>Blog RSS feed for rickyrosario.com</description>
<lastBuildDate><%= ViewData.Model.First().DatePublished.Value.ToUniversalTime().ToString("r") %></lastBuildDate>
<language>en-us</language>
<% foreach (Post p in ViewData.Model)  %>
    <item>
    <title><%= Html.Encode(p.Title) %></title>
    <link>http://<%= Request.Url.Host + Url.Action("ViewPostByName", new RouteValueDictionary(new  name = p.Name )) %></link>
    <guid>http://<%= Request.Url.Host + Url.Action("ViewPostByName", new RouteValueDictionary(new  name = p.Name )) %></guid>
    <pubDate><%= p.DatePublished.Value.ToUniversalTime().ToString("r") %></pubDate>
    <description><%= Html.Encode(p.Content) %></description>
    </item>
<%  %>
</channel>
</rss>

欲了解更多信息,请查看(无耻插件)http://rickyrosario.com/blog/creating-an-rss-feed-in-asp-net-mvc

【讨论】:

供 Razor 使用:@model PageModel @Response.ContentType = "application/rss+xml"; 什么开销?你的意思是你编写更少的代码来以更易读的方式完成同样的事情?【参考方案4】:

.NET 框架公开了处理联合的类:SyndicationFeed 等。 因此,与其自己进行渲染或使用其他建议的 RSS 库,为什么不让框架来处理它呢?

基本上,您只需要以下自定义 ActionResult 即可:

public class RssActionResult : ActionResult

    public SyndicationFeed Feed  get; set; 

    public override void ExecuteResult(ControllerContext context)
    
        context.HttpContext.Response.ContentType = "application/rss+xml";

        Rss20FeedFormatter rssFormatter = new Rss20FeedFormatter(Feed);
        using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
        
            rssFormatter.WriteTo(writer);
        
    

现在在您的控制器操作中,您可以简单地返回以下内容:

return new RssActionResult()  Feed = myFeedInstance ;

在我的博客http://www.developerzen.com/2009/01/11/aspnet-mvc-rss-feed-action-result/上有一个完整的示例

【讨论】:

【参考方案5】:

这是我从 Eran Kampf 和 Scott Hanselman 的视频(忘记链接)那里得到的,所以它与这里的其他一些帖子略有不同,但希望对您有所帮助,并准备好复制粘贴作为示例 rss 提要。

From my blog

Eran Kampf

using System;
using System.Collections.Generic;
using System.ServiceModel.Syndication;
using System.Web;
using System.Web.Mvc;
using System.Xml;

namespace MVC3javascript_3_2012.Rss

    public class RssFeed : FileResult
    
        private Uri _currentUrl;
        private readonly string _title;
        private readonly string _description;
        private readonly List<SyndicationItem> _items;

        public RssFeed(string contentType, string title, string description, List<SyndicationItem> items)
            : base(contentType)
        
            _title = title;
            _description = description;
            _items = items;
        

        protected override void WriteFile(HttpResponseBase response)
        
            var feed = new SyndicationFeed(title: this._title, description: _description, feedAlternateLink: _currentUrl,
                                           items: this._items);
            var formatter = new Rss20FeedFormatter(feed);
            using (var writer = XmlWriter.Create(response.Output))
            
                formatter.WriteTo(writer);
            
        

        public override void ExecuteResult(ControllerContext context)
        
            _currentUrl = context.RequestContext.HttpContext.Request.Url;
            base.ExecuteResult(context);
        
    

还有控制器代码....

    [HttpGet]
public ActionResult RssFeed()

    var items = new List<SyndicationItem>();
    for (int i = 0; i < 20; i++)
    
        var item = new SyndicationItem()
        
            Id = Guid.NewGuid().ToString(),
            Title = SyndicationContent.CreatePlaintextContent(String.Format("My Title 0", Guid.NewGuid())),
            Content = SyndicationContent.CreateHtmlContent("Content The stuff."),
            PublishDate = DateTime.Now
        ;
        item.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://www.google.com")));//Nothing alternate about it. It is the MAIN link for the item.
        items.Add(item);
    

    return new RssFeed(title: "Greatness",
                       items: items,
                       contentType: "application/rss+xml",
                       description: String.Format("Sooper Dooper 0", Guid.NewGuid()));


【讨论】:

以上是关于ASP.NET MVC 中的 RSS 源的主要内容,如果未能解决你的问题,请参考以下文章

新手轻松学会MVC

是否可以在 ASP.NET MVC 的脚本块中引用 ViewData?

带有 ASP.NET MVC 的 jquery - 调用启用 ajax 的 Web 服务

在VS2010 ASP.NET开发服务器上运行新的MVC3解决方案;会员数据库在哪里?

如何使用 Angular 2 在 POST 上启用 ASP.NET MVC 4 中的跨源请求

ASP.NET MVC 网站开发总结——校友平台开发总结