Nguồn cấp dữ liệu RSS trong ASP.NET MVC


113

Bạn sẽ đề xuất xử lý Nguồn cấp RSS trong ASP.NET MVC như thế nào? Sử dụng thư viện của bên thứ ba? Sử dụng công cụ RSS trong BCL? Chỉ tạo một dạng xem RSS kết xuất XML? Hay một cái gì đó hoàn toàn khác?


Sử dụng RssToolkit, bạn chỉ cần có một tệp .ashx duy nhất trong dự án của mình để tạo nguồn cấp RSS. Sau đó, bạn có thể viết lại URL của nó thành một URL thân thiện. Tôi nghĩ rằng không có bất cứ điều gì chống lại MVC trong cách tiếp cận này.
Mahdi Taghizadeh

Đây là một bài đăng tiếp theo đưa ý tưởng RssActionResult đi xa hơn một chút với lớp kết quả SyndicationAction tổng quát cũng như bộ lọc lấy có điều kiện 304 NotModified. 58bits.com/blog/…
Blue Waters,

Tôi đã viết một RssResult mà bạn có thể xem nếu muốn. Nó phải đáp ứng yêu cầu của bạn http://www.wduffy.co.uk/blog/rssresult-aspnet-mvc-rss-actionresult/
WDuffy

1
Chỉ cần cập nhật câu hỏi này kể từ 18 tháng sau lần chỉnh sửa cuối cùng - Có vẻ hợp lý khi đặt câu hỏi "mọi thứ đã thay đổi khi lặp lại cả .net và mvc sẽ thay đổi cách chúng tôi tiếp cận vấn đề quản lý nguồn cấp dữ liệu"? Sự đồng thuận (thông qua một chuỗi SO khác) là, 'Không có thay đổi cơ bản - đây vẫn là tập hợp các lựa chọn thay thế tốt nhất của bạn.'
justSteve

gợi ý xấu cho ASP.NET MVC.
tugberk

Câu trả lời:


64

Đây là những gì tôi khuyên bạn nên:

  1. Tạo một lớp có tên RssResult kế thừa lớp cơ sở trừu tượng ActionResult.
  2. Ghi đè phương thức ExecuteResult.
  3. ExecuteResult có ControllerContext được người gọi chuyển tới nó và với điều này, bạn có thể lấy dữ liệu và kiểu nội dung.
  4. Khi bạn thay đổi loại nội dung thành rss, bạn sẽ muốn tuần tự hóa dữ liệu sang RSS (sử dụng mã của riêng bạn hoặc thư viện khác) và ghi vào phản hồi.

  5. Tạo một hành động trên bộ điều khiển mà bạn muốn trả về rss và đặt kiểu trả về là RssResult. Lấy dữ liệu từ mô hình của bạn dựa trên những gì bạn muốn trả lại.

  6. Sau đó, bất kỳ yêu cầu nào đối với hành động này sẽ nhận được rs của bất kỳ dữ liệu nào bạn chọn.

Đó có lẽ là cách nhanh nhất và có thể tái sử dụng để trả về rss có phản hồi cho một yêu cầu trong ASP.NET MVC.


10
Hanselman có một giải pháp tương tự (video: bắt đầu từ khoảng 41m) mà anh ấy kế thừa từ FileResult. Bằng cách đó, bạn có thể gọi hàm tạo của lớp base("application/rss+xml")và tránh các bước 3 và 4. Anh ta ghi đè ExecuteResult, nhưng nó không quan trọng. Ông cũng tắt rất nhiều mã thường-dệt ở nhà và sử dụng các tính năng của 3.5+ SyndicateItem, SyndicateFeedRss20FeedFormatter.
Patridge

@Dale: có thể ghi vào phản hồi khi bạn muốn xuất ra nguồn cấp dữ liệu cho chế độ xem một phần không? Cảm ơn.
Christian

1
Liên kết cập nhật của video Hanselman từ nhận xét trước của tôi.
patridge

150

Khuôn khổ .NET hiển thị các lớp xử lý việc phân phối: SyndicationFeed, v.v. Vì vậy, thay vì tự mình thực hiện việc kết xuất hoặc sử dụng một số thư viện RSS được đề xuất khác, tại sao không để khuôn khổ xử lý nó?

Về cơ bản, bạn chỉ cần ActionResult tùy chỉnh sau đây và bạn đã sẵn sàng:

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);
        }
    }
}

Bây giờ trong hành động điều khiển của bạn, bạn có thể đơn giản trả lại như sau:

return new RssActionResult() { Feed = myFeedInstance };

Có một mẫu đầy đủ trên blog của tôi tại http://www.developerzen.com/2009/01/11/aspnet-mvc-rss-feed-action-result/


34

Tôi đồng ý với Haacked. Tôi hiện đang triển khai trang web / blog của mình bằng cách sử dụng khuôn khổ MVC và tôi đã thực hiện với cách tiếp cận đơn giản là tạo Chế độ xem mới cho 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>

Để biết thêm thông tin, hãy xem (phích cắm vô liêm sỉ) http://rickyrosario.com/blog/creating-an-rss-feed-in-asp-net-mvc


4
để sử dụng Razor: @model PageModel @ {Response.ContentType = "application / rss + xml"; } <? xml version = "1.0" encoding = "UTF-8"?>
Anthony Johnston

2
Chi phí gì? ý bạn là thực tế là bạn đang viết ít mã hơn để hoàn thành điều tương tự theo cách dễ đọc hơn?
Paul

12

Một cách tiếp cận điên rồ khác, nhưng có ưu điểm của nó là sử dụng chế độ xem .aspx bình thường để hiển thị RSS. Trong phương pháp hành động của bạn, chỉ cần đặt loại nội dung thích hợp. Một lợi ích của phương pháp này là dễ dàng hiểu được những gì đang được hiển thị và cách thêm các yếu tố tùy chỉnh như vị trí địa lý.

Sau đó, một lần nữa, các cách tiếp cận khác được liệt kê có thể tốt hơn, chỉ là tôi chưa sử dụng chúng. ;)


3
@Haacked: Thế giới đầy RSS XML không hợp lệ được tạo bởi một hệ thống tạo khuôn mẫu. Xin đừng thêm vào mớ hỗn độn! Ricky, HTML encoding! = Mã hóa XML.
Brad Wilson

Dưới đây là tài liệu về Mã hóa Html từ MSDN:> Do chi tiết triển khai hiện tại, hàm này có thể được sử dụng như một hàm xmlEncode. Hiện tại, tất cả các thực thể được đặt tên được sử dụng bởi hàm này cũng là các thực thể có tên được xác định trước xml. Chúng được <> "& mã hóa dưới dạng & lt; & gt; & quot; và & amp ;. Các thực thể khác được mã hóa theo hệ thập phân như & # 160 ;. http://msdn.microsoft.com/en-us/library/73z22y6h.aspx
Ricky

Làm thế nào bạn có thể đảm bảo XML hợp lệ khi làm theo cách này? Sẽ thật tuyệt nếu việc hiển thị dạng xem được tách khỏi một yêu cầu web đến, để tạo các dạng xem XML hoặc các mẫu email như ruby ​​hoàn chỉnh trên đường ray có thể thực hiện được.
Paco

Thay vì sử dụng công cụ chế độ xem, bạn có thể tạo RssResult có nguồn gốc từ ActionResult. Chúng tôi làm điều này với JsonResult tuần tự hóa đối tượng thành JSON. Trong trường hợp của bạn, bạn sẽ tìm thấy một số bộ tuần tự (tôi nghĩ WCF có một bộ) tuần tự hóa thành RSS.
Haacked

8

Tôi nhận được cái này từ Eran Kampf và một vid của Scott Hanselman (quên liên kết) vì vậy nó chỉ hơi khác so với một số bài đăng khác ở đây, nhưng hy vọng hữu ích và sao chép dán sẵn sàng làm nguồn cấp dữ liệu rss ví dụ.

Từ blog của tôi

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);
        }
    }
}

Và Mã điều khiển….

    [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()));

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.