ASP.NET 使用 SyndicationFeed 输出 Rss

以前生成 RSS 都是使用拼接 Xml 的方式生成的,不仅麻烦而且还不规范。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#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 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/// <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 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/// <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);
        }
    }
}

最后上一张效果图:

posted @   Charles Zhang  阅读(1598)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示