以前生成 RSS 都是使用拼接 Xml 的方式生成的,不仅麻烦而且还不规范。
#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"?>
");
xml.Append("<rss version="2.0">
");
xml.Append("<channel>
");
CategoryInfo category = new CategoryInfo();
if (categoryId == 0 && string.IsNullOrEmpty(customUrl))
{
xml.AppendFormat("<title>{0}</title>
", 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>
", string.Format(MemoryCacheProvider.GetLanguage("WebCategoryRssTitle", WeilogContext.Current.Application.Prefix), category.Name, SettingInfo.Name));
}
else
{
category = CategoryService.GetCategory(Provider, categoryId);
xml.AppendFormat("<title>{0}</title>
", string.Format(MemoryCacheProvider.GetLanguage("WebCategoryRssTitle", WeilogContext.Current.Application.Prefix), category.Name, SettingInfo.Name));
}
xml.AppendFormat("<link>{0}</link>
", SettingInfo.Url);
xml.AppendFormat("<description>{0}</description>
", SettingInfo.Description);
xml.AppendFormat("<language>{0}</language>
", SettingInfo.Language);// <language>zh-cn</language>
xml.AppendFormat("<copyright>{0}</copyright>
", "Copyright " + SettingInfo.Name);
xml.AppendFormat("<webMaster>{0}</webMaster>
", SettingInfo.SmtpMail);
xml.AppendFormat("<generator>{0}</generator>
", WeilogContext.Current.Application.FullVersion);
xml.Append("<image>
");
xml.AppendFormat(" <title>{0}</title>
", SettingInfo.Name);
xml.AppendFormat(" <url>{0}</url>
", "/Common/Images/Logo.jpg");
xml.AppendFormat(" <link>{0}</link>
", SettingInfo.Url);
xml.AppendFormat(" <description>{0}</description>
", SettingInfo.Description);
xml.Append("</image>
");
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>
");
xml.AppendFormat(" <link>{0}</link>
", string.Format(SitePath.PostLinkFormat, SettingInfo.Url, item.Locator));
xml.AppendFormat(" <title>{0}</title>
", item.Title);
xml.AppendFormat(" <author>{0}</author>
", item.AuthorName);
xml.AppendFormat(" <category>{0}</category>
", CategoryService.GetCategory(Provider, item.CategoryId).Name);
xml.AppendFormat(" <pubDate>{0}</pubDate>
", item.PublishTime);
//xml.AppendFormat(" <guid>{0}</guid>
", string.Format(WebPath.PostLinkFormat, SettingInfo.Url, item.CustomUrl));
xml.AppendFormat(" <description>{0}</description>
", StringUtil.CDATA(string.IsNullOrEmpty(item.Password) ? (SettingInfo.RssType == 0 ? item.Excerpt : item.Content) : MemoryCacheProvider.GetLanguage("MsgEncContent", WeilogContext.Current.Application.Prefix)));
xml.Append("</item>
");
}
xml.Append("</channel>
");
xml.Append("</rss>");
HttpContext.Current.Response.ContentType = "text/xml";
HttpContext.Current.Response.Write(xml);
}
#endregion
前段时间看老外的项目里用到了 SyndicationFeed 这个类来生成 Rss,索性自己做项目的时候也用了一下,果然事半功倍,只需要简洁的代码便可输出 Rss。我的项目是 MVC 的。
/// <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);
}
}
}
最后上一张效果图:
