RSS馈送生成自定义RSSResult

当我以前看过在ASP.NET MVC中产生RSS源时,我使用ContentResult方法返回XML。最佳实践表明,如果需要,您应该创建新的ActionResult。所以这篇文章看起来创建一个RSSResult,以及不同的方式来生成饲料本身。

如果你看看 上一篇文章及其评论,您可以看到有许多方法可以在ASP.NET MVC中生产RSS源。有些人觉得你应该从控制器返回一个模型,并在视图中格式化它,其他人都很高兴根本不具有视图。我并不热衷于将XML返回到视图模板的想法。它易于验证错误,因为它要求您手动构建XML。在我之前的文章中使用LINQ到XML的方法可以说也是如此。但是,在WCF中有一个 RSS20FeedFeamatter. 解决问题的课程。

我要从RSSResult本身开始。这源于ActionResult,executeresult()方法是过度ridden。你会注意到 system.servicemodel.syndication. 出现在上面。这是通过添加引用来提供的 system.servicemodel.web.。 RSS和Atom的饲料格式化 system.servicemodel.syndication.。 rssresult类具有一个syndicationfeed属性,它将传递给RSS20FeedFormatter对象,它具有WriteTo()方法。这需要XMLWRITER,并且只需生成XML。

using System;
using system.servicemodel.syndication.;
using System.Web.Mvc;
using System.Xml;

namespace MikesDotnetting.Models
{
    public class RssResult : ActionResult
    {
        public syndicationfeed Feed { private get; set; }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            context.HttpContext.Response.ContentType = "text/xml";

            var rssFormatter = new RSS20FeedFeamatter.(Feed);
            using (var writer = XmlWriter.Create(context.HttpContext.Response.Output))
            {
                rssFormatter.WriteTo(writer);
            }
        }
    }
}

目前,如果您在控制器中生成Feed对象,则必须调用类似的actionResult:

return new RssResult() {Feed = feed};

理想情况下,我们希望对ActionResult的调用类似于现有框架ActionResult的速记( 返回视图() 代替 返回新viewresult()等等)所以我要创建一个basexmlController来帮助:

using system.servicemodel.syndication.;
using System.Web.Mvc;
using MikesDotnetting.Models;


namespace MikesDotnetting.Controllers
{
    public class BaseXmlController : Controller
    {
        protected static RssResult Rss(syndicationfeed feed)
        {
            return new RssResult
            {
                Feed = feed
            };
        }


    }
}

现在,与框架actionResults一样,有一种称为RSS()的方法,它包装了RSSResult构造。所以我们将看看控制器操作:

[OutputCache(VaryByParam = "none", Duration = 3600)]
public RssResult RssFeed()
{
    const string url = "http://www.lssc9d.icu/Article/{0}/{1}";
    var posts = repository.GetRSSFeed();
    var feed = new syndicationfeed("mikesdotnetting. News Feed",
                    "Latest additions to Mikesdotnetting",
                    new Uri("http://www.lssc9d.icu/rss"))
                                 {
                                     Copyright =
                                             new TextSyndicationContent("(c)" + DateTime.Now.Year +
                                             ", Mikesdotnetting. All rights reserved")
                                 };
    var items = new List<SyndicationItem.>();
    foreach (var post in posts)
    {
        var item = new SyndicationItem.(
        			post.Head,
                    post.Intro,
                    new Uri(String.Format(url,
                    	post.ID,
                        post.Head.ToCleanUrl())),
                    post.ID.ToString(),
                    post.CreatedDate
                    );
        items.Add(item);
    }
    feed.Items = items;
    return Rss(feed);
}

我已经向这个动作添加了缓存,虽然我给出的时间是有点乐观。我的RSS源每周更改一次,平均每周更改一次,但至少人们可以在其中一小时内看到新物品,当他们最终将它达到我的网站时出现。但是您可以在工作中看到一些同步课程。顶级级别是一个 syndicationfeed 对象,由集合组成 SyndicationItem. 对象。 tocleanurl()是一个我创建的扩展方法,以格式化物品标题以与URL一起播放。

这种方法肯定会缓解生成有效RSS源的负担,因为框架为您提供此操作。使用自定义ActionResults也非常好地揭示了意图。读取此方法代码的人毫无疑问旨在产生什么。