RSS-канали в ASP.NET MVC


113

Як би ви рекомендували обробляти RSS-канали в ASP.NET MVC? Використовуєте сторонню бібліотеку? Використовуєте RSS-матеріали в BCL? Просто робиться перегляд RSS, який надає XML? Або щось зовсім інше?


Використовуючи RssToolkit, вам просто потрібно мати один файл .ashx у вашому проекті, щоб генерувати RSS-канал. Тоді ви можете переписати його URL-адресу на дружню. Я думаю, що в цьому підході немає нічого проти MVC.
Махді Тагізаде

Ось подальший пост, який піднімає ідею RssActionResult трохи далі з узагальненим класом результатів SyndicationAction, а також 304 NotModified умовним фільтром отримання. 58bits.com/blog/…
Блакитні води

Я написав RssResult, який ви можете подивитися, якщо вам подобається. Він повинен відповідати вашим вимогам http://www.wduffy.co.uk/blog/rssresult-aspnet-mvc-rss-actionresult/
WDuffy

1
Просто для оновлення цього питання станом на 18 місяців після останнього редагування - здавалося, розумним є питання "чи змінилися речі з ітераціями як .net, так і mvc, що змінило б те, як ми підійдемо до проблеми управління каналами"? Консенсус (через іншу тему SO) полягає в тому, що "Немає кардинальних змін - це залишається найкращим набором альтернатив".
justSteve

погана пропозиція для ASP.NET MVC.
тугберк

Відповіді:


64

Ось що я рекомендую:

  1. Створіть клас під назвою RssResult, який успадковує абстрактний базовий клас ActionResult.
  2. Замініть метод ExecuteResult.
  3. ExecuteResult передає йому абонент ControllerContext, і за допомогою цього ви можете отримати дані та тип вмісту.
  4. Після зміни типу вмісту на rss, ви захочете серіалізувати дані до RSS (використовуючи власний код або іншу бібліотеку) і написати відповідь.

  5. Створіть дію на контролері, якому потрібно повернути rss, і встановіть тип повернення як RssResult. Візьміть дані з вашої моделі на основі того, що ви хочете повернути.

  6. Тоді будь-який запит на цю дію отримає rss будь-яких даних, які ви обрали.

Це, мабуть, найшвидший і багаторазовий спосіб повернення rss має відповідь на запит в ASP.NET MVC.


10
Hanselman має подібне рішення (відео: починаючи приблизно з 41 м), де він успадковує від FileResult. Роблячи це, ви можете викликати конструктор свого класу base("application/rss+xml")і уникати кроків 3 і 4. Він переосмислює ExecuteResult, але це не є життєво важливим. Він також ярлики багато типово домотканого коду і використовує 3.5+ особливості SyndicateItem, SyndicateFeedі Rss20FeedFormatter.
патрон

@Dale: чи можна написати відповідь, коли ви хочете вивести подачу для часткового перегляду? Дякую.
Крістіан

1
Оновлено посилання відео Hanselman з мого попереднього коментаря.
патрон

150

Структура .NET розкриває класи, які обробляють синдикацію: SyndicationFeed і т. Д. Тож замість того, щоб робити самому рендеринг або використовувати якусь іншу запропоновану бібліотеку RSS, чому б не дозволити фреймворку подбати про це?

По суті, вам просто потрібні такі користувальницькі ActionResult, і ви готові піти:

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

Тепер у дії контролера ви можете просто повернути наступне:

return new RssActionResult() { Feed = myFeedInstance };

На моєму блозі є повний зразок за адресою http://www.developerzen.com/2009/01/11/aspnet-mvc-rss-feed-action-result/


34

Я згоден з Haacked. Наразі я реалізую свій сайт / блог за допомогою MVC фрейму, і я пішов з простим підходом до створення нового Погляду для 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>

Для отримання додаткової інформації перевірте (безсоромний штекер) http://rickyrosario.com/blog/creating-an-rss-feed-in-asp-net-mvc


4
для використання Razor: @model PageModel @ {Response.ContentType = "application / rss + xml"; } <? xml version = "1.0" encoding = "UTF-8"?>
Ентоні Джонстон

2
Що над головою? ви маєте на увазі той факт, що ви пишете менше коду, щоб виконати ту саму річ більш читабельним способом?
Павло

12

Ще один шалений підхід, але має свою перевагу, полягає у використанні нормального перегляду .aspx для візуалізації RSS. У своєму способі дії просто встановіть відповідний тип вмісту. Одна з переваг такого підходу - це легко зрозуміти, що відображається, і як додати спеціальні елементи, такі як геолокація.

Потім знову можуть бути кращі інші перелічені підходи, я просто не використовував їх. ;)


3
@Haacked: Світ переповнений недійсним RSS XML, що генерується системою шаблонів. Будь ласка, не додайте до безладу! Рікі, кодування HTML! = Кодування XML.
Бред Уілсон

Нижче представлена ​​документація Html Encode від MSDN:> Завдяки поточним деталям реалізації, ця функція може використовуватися як функція xmlEncode. В даний час усі названі об'єкти, які використовуються за допомогою цієї функції, також є попередньо визначеними іменами об'єкти xml. Вони є <> "& закодований як & ЛТ; & GT; & Quot; і & амп;. Інші суті десяткової кодуванні , як & # 160;. Http://msdn.microsoft.com/en-us/library/73z22y6h.aspx
Ріккі

Як ви можете переконатися, що XML дійсний таким чином? Було б добре, якби візуалізація перегляду була від'єднана від вхідного веб-запиту, щоб зробити можливим перегляд XML або шаблони електронної пошти, як зроблено рубін на рейках.
Пако

Замість того, щоб використовувати механізм перегляду, ви можете створити RssResult, який походить від ActionResult. Ми робимо це за допомогою JsonResult, який серіалізує об'єкт до JSON. У вашому випадку ви знайдете серіалізатор (я думаю, у WCF є такий), який серіалізується на RSS.
Зламаний

8

Я отримав це від Eran Kampf та Scott Hanselman vid (забув посилання), тому він лише трохи відрізняється від деяких інших публікацій тут, але, сподіваємось, корисний і скопіюйте готову пасту як приклад RSS-каналу.

З мого блогу

Еран Кампф

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

І Код контролера ....

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

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.