ASP.NET 使用 SyndicationFeed 輸出 Rss

之前生成 RSS 都是使用拼接 Xml 的方式生成的,不只麻煩並且還不規範。web

        #region 輸出指定分類編號的消息源內容...

        /// <summary>
        /// 輸出指定分類編號的消息源內容。
        /// </summary>
        public void OutputFeed()
        {
            //int categoryId, string customUrl
            int categoryId = 0;
            string customUrl = string.Empty;
            if (!string.IsNullOrEmpty(RequestUtility.GetQueryString("CategoryId")))
            {
                categoryId = Convert.ToInt32(RequestUtility.GetQueryString("CategoryId"));
            }
            if (!string.IsNullOrEmpty(RequestUtility.GetQueryString("Custom")))
            {
                customUrl = RequestUtility.GetQueryString("Custom");
            }
            StringBuilder xml = new StringBuilder();
            xml.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
            xml.Append("<rss version=\"2.0\">\n");
            xml.Append("<channel>\n");
            CategoryInfo category = new CategoryInfo();
            if (categoryId == 0 && string.IsNullOrEmpty(customUrl))
            {
                xml.AppendFormat("<title>{0}</title>\n", string.Format(MemoryCacheProvider.GetLanguage("WebRssTitle", WeilogContext.Current.Application.Prefix), SettingInfo.Name));
            }
            else if (categoryId == 0 && !string.IsNullOrEmpty(customUrl))
            {
                category = CategoryService.GetCategory(Provider, customUrl);
                xml.AppendFormat("<title>{0}</title>\n", string.Format(MemoryCacheProvider.GetLanguage("WebCategoryRssTitle", WeilogContext.Current.Application.Prefix), category.Name, SettingInfo.Name));
            }
            else
            {
                category = CategoryService.GetCategory(Provider, categoryId);
                xml.AppendFormat("<title>{0}</title>\n", string.Format(MemoryCacheProvider.GetLanguage("WebCategoryRssTitle", WeilogContext.Current.Application.Prefix), category.Name, SettingInfo.Name));
            }
            xml.AppendFormat("<link>{0}</link>\n", SettingInfo.Url);
            xml.AppendFormat("<description>{0}</description>\n", SettingInfo.Description);
            xml.AppendFormat("<language>{0}</language>\n", SettingInfo.Language);//    <language>zh-cn</language>
            xml.AppendFormat("<copyright>{0}</copyright>\n", "Copyright " + SettingInfo.Name);
            xml.AppendFormat("<webMaster>{0}</webMaster>\n", SettingInfo.SmtpMail);
            xml.AppendFormat("<generator>{0}</generator>\n", WeilogContext.Current.Application.FullVersion);
            xml.Append("<image>\n");
            xml.AppendFormat("\t<title>{0}</title>\n", SettingInfo.Name);
            xml.AppendFormat("\t<url>{0}</url>\n", "/Common/Images/Logo.jpg");
            xml.AppendFormat("\t<link>{0}</link>\n", SettingInfo.Url);
            xml.AppendFormat("\t<description>{0}</description>\n", SettingInfo.Description);
            xml.Append("</image>\n");
            int totalRecords = 0;
            List<PostInfo> articleList = new List<PostInfo>();
            articleList = PostService.GetPostList(base.Provider, categoryId, null, null, PostType.Post, null, null, null, OrderField.ByPublishTime, OrderType.Desc, 1, 20, out totalRecords);
            foreach (PostInfo item in articleList)
            {
                xml.Append("<item>\n");
                xml.AppendFormat("\t<link>{0}</link>\n", string.Format(SitePath.PostLinkFormat, SettingInfo.Url, item.Locator));
                xml.AppendFormat("\t<title>{0}</title>\n", item.Title);
                xml.AppendFormat("\t<author>{0}</author>\n", item.AuthorName);
                xml.AppendFormat("\t<category>{0}</category>\n", CategoryService.GetCategory(Provider, item.CategoryId).Name);
                xml.AppendFormat("\t<pubDate>{0}</pubDate>\n", item.PublishTime);
                //xml.AppendFormat("\t<guid>{0}</guid>\n", string.Format(WebPath.PostLinkFormat, SettingInfo.Url, item.CustomUrl));
                xml.AppendFormat("\t<description>{0}</description>\n", StringUtil.CDATA(string.IsNullOrEmpty(item.Password) ? (SettingInfo.RssType == 0 ? item.Excerpt : item.Content) : MemoryCacheProvider.GetLanguage("MsgEncContent", WeilogContext.Current.Application.Prefix)));
                xml.Append("</item>\n");
            }
            xml.Append("</channel>\n");
            xml.Append("</rss>");
            HttpContext.Current.Response.ContentType = "text/xml";
            HttpContext.Current.Response.Write(xml);
        }

        #endregion

前段時間看老外的項目裏用到了 SyndicationFeed 這個類來生成 Rss,索性本身作項目的時候也用了一下,果真事半功倍,只須要簡潔的代碼即可輸出 Rss。個人項目是 MVC 的。app

        /// <summary>
        /// 文章訂閱。
        /// </summary>
        /// <returns>視圖的執行結果。</returns>
        public ActionResult PostFeed()
        {
            var feed = new SyndicationFeed(
                                    base.Settings["Name"].ToString(),
                                    base.Settings["Description"].ToString(),
                                    new Uri(Settings["Url"].ToString()),
                                    "BlogRSS",
                                    DateTime.UtcNow);

            if (!(bool)Settings["Status"])
                return new FeedActionResult() { Feed = feed };

            var items = new List<SyndicationItem>();
            var posts = PostService.GetPostList(Provider, Data.Common.OrderField.ByPublishTime, Data.Common.OrderType.Desc, 20);
            foreach (var post in posts)
            {
                string blogPostUrl = Url.RouteUrl("Post", new { Id = post.Id }, "http");
                items.Add(new SyndicationItem(post.Title, post.Content, new Uri(blogPostUrl), String.Format("Blog:{0}", post.Id), post.PublishTime));
            }
            feed.Items = items;
            return new FeedResult() { Feed = feed };
        }

FeedResult 是一個自定義的 ActionResult 類:框架

    /// <summary>
    /// 封裝一個 RSS 源操做方法的結果並用於表明該操做方法執行框架級操做。
    /// </summary>
    public class FeedResult : ActionResult
    {
        /// <summary>
        /// 聲明 RSS 源對象。
        /// </summary>
        public SyndicationFeed Feed { get; set; }

        /// <summary>
        /// 初始化 <see cref="FeedResult"/> 類的新實例。
        /// </summary>
        public FeedResult()
        { 
        }

        /// <summary>
        /// 經過從 System.Web.Mvc.ActionResult 類繼承的自定義類型,啓用對操做方法結果的處理。
        /// </summary>
        /// <param name="context">用於執行結果的上下文。 上下文信息包括控制器、HTTP 內容、請求上下文和路由數據。</param>
        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.ContentType = "application/rss+xml";

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

最後上一張效果圖:ide

相關文章
相關標籤/搜索