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.