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

Как бы вы рекомендовали обрабатывать RSS-каналы в ASP.NET MVC? Используете стороннюю библиотеку? Используете материал RSS в BCL? Просто делаете просмотр RSS, который отображает XML? Или что-то совершенно другое?

15.08.2008 02:56:41
Используя RssToolkit, вам просто нужно иметь один файл .ashx в вашем проекте для генерации RSS-канала. Затем вы можете переписать его URL на дружественный. Я думаю, что нет ничего против MVC в этом подходе.
Mahdi Taghizadeh 12.11.2008 19:43:25
Вот следующий пост, в котором идея RssActionResult идет немного дальше с обобщенным классом результатов SyndicationAction, а также условным фильтром 304 NotModified. 58bits.com/blog/…
Blue Waters 29.07.2009 05:36:43
Я написал RssResult, который вы можете посмотреть, если хотите. Он должен соответствовать вашим требованиям http://www.wduffy.co.uk/blog/rssresult-aspnet-mvc-rss-actionresult/
WDuffy 29.10.2009 11:42:25
Просто чтобы обновить этот вопрос через 18 месяцев после последнего редактирования - казалось разумным задаться вопросом: «Изменились ли изменения с итерациями как в .net, так и в mvc, что изменит наш подход к проблеме управления фидами»? Консенсус (через другой поток SO) заключается в том, что «никаких фундаментальных изменений - это ваш лучший набор альтернатив».
justSteve 7.03.2011 15:35:00
плохое предложение для ASP.NET MVC.
tugberk 18.12.2011 18:14:19
5 ОТВЕТОВ
РЕШЕНИЕ

Вот что я рекомендую:

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

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

  6. Тогда любой запрос на это действие получит rss любых данных, которые вы выберете.

Вероятно, это самый быстрый и многократно используемый способ возврата rss - ответ на запрос в ASP.NET MVC.

64
15.08.2008 03:18:50
У Хансельмана есть похожее решение (видео: начиная с 41 м), где он наследует от FileResult. Таким образом, вы можете вызвать конструктор вашего класса base("application/rss+xml")и избежать шагов 3 и 4. Он переопределяет ExecuteResult, но это не жизненно важно. Он также сочетает в себе много типичного кода и использует функции 3.5+ SyndicateItem, SyndicateFeedи Rss20FeedFormatter.
patridge 21.07.2010 22:04:38
@ Дейл: возможно ли написать ответ, если вы хотите вывести его на частичное представление? Спасибо.
Christian 8.08.2011 07:40:00
Обновленная ссылка на видео Хансельмана из моего предыдущего комментария.
patridge 2.07.2012 16:54:43

Еще один сумасшедший подход, но он имеет преимущество, заключается в использовании обычного представления .aspx для рендеринга RSS. В вашем методе действия просто установите соответствующий тип контента. Одно из преимуществ этого подхода заключается в том, что легко понять, что отображается, и как добавить пользовательские элементы, такие как геолокация.

Опять же, другие перечисленные подходы могут быть лучше, я просто не использовал их. ;)

12
15.08.2008 05:49:33
@Haacked: мир полон недействительных RSS XML, сгенерированных системой шаблонов. Пожалуйста, не добавляйте в беспорядок! Рики, кодировка HTML! = Кодировка XML.
Brad Wilson 17.08.2008 16:01:20
Ниже приведена документация по Html Encode из MSDN:> Из-за текущих деталей реализации эту функцию можно использовать как функцию xmlEncode. В настоящее время все именованные объекты, используемые этой функцией, также являются предварительно определенными именованными объектами xml. Они <> "& кодируются как & lt; & gt; & quot; и & amp;. Другие объекты имеют десятичное кодирование, например & # 160 ;. http://msdn.microsoft.com/en-us/library/73z22y6h.aspx
Ricky 17.08.2008 22:54:10
Как вы можете убедиться, что XML действителен таким образом? Было бы хорошо, если бы рендеринг представлений был отделен от входящего веб-запроса, чтобы сделать возможными представления XML или шаблоны электронной почты, такие как done ruby ​​on rails.
Paco 12.11.2008 20:28:07
Вместо того, чтобы использовать движок представления, вы можете создать RssResult, производный от ActionResult. Мы делаем это с JsonResult, который сериализует объект в JSON. В вашем случае вы найдете какой-нибудь сериализатор (я думаю, что он есть в WCF), который сериализует в RSS.
Haacked 19.11.2008 08:49:10

Я согласен с 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

34
30.01.2010 02:25:24
для использования в Razor: @model PageModel @ {Response.ContentType = "application / rss + xml"; } <? xml version = "1.0" encoding = "UTF-8"?>
Anthony Johnston 21.01.2011 16:11:51
Какие накладные расходы? Вы имеете в виду тот факт, что вы пишете меньше кода, чтобы выполнить то же самое в более удобочитаемом виде?
Paul 6.03.2011 19:19:57

Платформа .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/

150
15.06.2009 05:38:07

Я получил это от Эрана Кампфа и видео Скотта Хансельмана (забыл ссылку), так что оно лишь немного отличается от некоторых других постов здесь, но, надеюсь, будет полезным и скопировать пасту в качестве примера 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()));

}
8
10.06.2017 22:54:31