ASP.NET MVC'de RSS Akışları


113

ASP.NET MVC'de RSS Akışlarının işlenmesini nasıl önerirsiniz? Üçüncü taraf bir kitaplık mı kullanıyorsunuz? BCL'deki RSS öğelerini kullanıyor musunuz? XML'i oluşturan bir RSS görünümü mü yapıyorsunuz? Veya tamamen farklı bir şey?


RssToolkit'i kullanarak, RSS beslemesi oluşturmak için projenizde tek bir .ashx dosyasına ihtiyacınız vardır. Ardından URL'sini dostça bir tane olarak yeniden yazabilirsiniz. Bu yaklaşımda MVC'ye karşı bir şey olmadığını düşünüyorum.
Mahdi Tağizadeh

Aşağıda, genelleştirilmiş bir SyndicationAction sonuç sınıfının yanı sıra 304 NotModified koşullu alma filtresi ile RssActionResult fikrini biraz daha ileri götüren bir takip gönderisi var. 58bits.com/blog/…
Blue Waters

İsterseniz bir göz atabileceğiniz bir RssResult yazdım. Gereksinimlerinizi karşılamalıdır http://www.wduffy.co.uk/blog/rssresult-aspnet-mvc-rss-actionresult/
WDuffy

1
Son düzenlemeyi takip eden 18 ay itibariyle bu soruyu güncellemek için - '.net ve mvc'ye yapılan yinelemelerde, yem yönetimi sorununa yaklaşım şeklimizi değiştirecek şeyler değişti mi' sorusu mantıklı görünüyordu? Fikir birliği (farklı bir SO iş parçacığı aracılığıyla), 'Temel bir değişiklik yok - bu sizin en iyi alternatifler kümeniz olarak kalır.'
justSteve

ASP.NET MVC için kötü öneri.
tugberk

Yanıtlar:


64

İşte tavsiye ettiğim şey:

  1. ActionResult soyut temel sınıfını miras alan RssResult adlı bir sınıf oluşturun.
  2. ExecuteResult yöntemini geçersiz kılın.
  3. ExecuteResult, arayan tarafından kendisine iletilen ControllerContext'e sahiptir ve bununla veri ve içerik türünü alabilirsiniz.
  4. İçerik türünü rss olarak değiştirdikten sonra, verileri RSS'ye serileştirmek (kendi kodunuzu veya başka bir kitaplığı kullanarak) ve yanıta yazmak isteyeceksiniz.

  5. Bir denetleyicide rss döndürmek istediğiniz bir eylem oluşturun ve dönüş türünü RssResult olarak ayarlayın. Neyi iade etmek istediğinize bağlı olarak modelinizden verileri alın.

  6. Daha sonra bu eyleme yönelik herhangi bir istek, seçtiğiniz verilerden rss alacaktır.

Bu muhtemelen rss döndürmenin en hızlı ve yeniden kullanılabilir yolu, ASP.NET MVC’deki bir isteğe yanıt verir.


10
Hanselman, FileResult'tan miras aldığı benzer bir çözüme (video: 41m civarında başlar) sahiptir. Bunu yaparak, sınıfınızın kurucusunu çağırabilir base("application/rss+xml")ve 3. ve 4. adımlardan kaçınabilirsiniz. ExecuteResult'u geçersiz kılar, ancak bu çok önemli değildir. O da tipik-homespun bir sürü kod kısayolları ve 3.5+ özelliklerini kullanan SyndicateItem, SyndicateFeedve Rss20FeedFormatter.
patridge

@Dale: Kısmi bir görünüme beslemek için çıktı almak istediğinizde yanıta yazmak mümkün mü? Teşekkürler.
Christian

1
Önceki yorumumdan Hanselman'ın videosunun güncellenmiş bağlantısı .
patridge

150

.NET çerçevesi, sendikasyonu işleyen sınıfları açığa çıkarır: SyndicationFeed vb. O halde, oluşturmayı kendiniz yapmak veya önerilen başka bir RSS kitaplığını kullanmak yerine, neden çerçevenin bunu yapmasına izin vermiyorsunuz?

Temel olarak aşağıdaki özel ActionResult'a ihtiyacınız var ve gitmeye hazırsınız:

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

Şimdi denetleyici eyleminizde aşağıdakileri basitçe geri döndürebilirsiniz:

return new RssActionResult() { Feed = myFeedInstance };

Http://www.developerzen.com/2009/01/11/aspnet-mvc-rss-feed-action-result/ adresindeki blogumda tam bir örnek var


34

Haacked'a katılıyorum. Şu anda sitemi / blogumu MVC çerçevesini kullanarak uyguluyorum ve RSS için yeni bir Görünüm oluşturmanın basit yaklaşımını uyguladım:

<%@ 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>

Daha fazla bilgi için (utanmaz eklenti) http://rickyrosario.com/blog/creating-an-rss-feed-in-asp-net-mvc adresine bakın


4
Razor kullanımı için: @model PageModel @ {Response.ContentType = "application / rss + xml"; } <? xml version = "1.0" encoding = "UTF-8"?>
Anthony Johnston

2
Ne ek yükü? Aynı şeyi daha okunaklı bir şekilde gerçekleştirmek için daha az kod yazdığınız gerçeğini mi kastediyorsunuz?
Paul

12

Başka bir çılgın yaklaşım, ancak bir avantajı da, RSS'yi oluşturmak için normal bir .aspx görünümü kullanmaktır. Eylem yönteminizde, sadece uygun içerik türünü ayarlayın. Bu yaklaşımın bir yararı, neyin oluşturulduğunu ve coğrafi konum gibi özel öğelerin nasıl ekleneceğini anlamanın kolay olmasıdır.

Sonra tekrar, listelenen diğer yaklaşımlar daha iyi olabilir, sadece onları kullanmadım. ;)


3
@Haacked: Dünya, bir şablonlama sistemi tarafından oluşturulan geçersiz RSS XML ile dolu. Lütfen ortalığı karıştırmayın! Ricky, HTML kodlaması! = XML kodlaması.
Brad Wilson

Aşağıda MSDN'den Html Encode'un dokümantasyonu bulunmaktadır:> Mevcut uygulama ayrıntıları nedeniyle, bu fonksiyon bir xmlEncode fonksiyonu olarak kullanılabilir. Şu anda, bu işlev tarafından kullanılan tüm adlandırılmış varlıklar aynı zamanda xml önceden tanımlanmış adlandırılmış varlıklardır. Bunlar <> "& & lt; & gt; & quot; ve & amp; olarak kodlanmıştır. Diğer varlıklar & # 160; gibi ondalık olarak kodlanmıştır. Http://msdn.microsoft.com/en-us/library/73z22y6h.aspx
Ricky

Bu şekilde XML'in geçerli olduğundan nasıl emin olabilirsiniz? Görünüm oluşturmanın gelen bir web isteğinden ayrıştırılması, XML görünümlerinin veya done Ruby on rails gibi e-posta şablonlarının mümkün olması güzel olurdu.
Paco

Bir görünüm motoru kullanmak yerine, ActionResult'tan türetilen bir RssResult oluşturabilirsiniz. Bunu nesneyi JSON'a serileştiren JsonResult ile yapıyoruz. Sizin durumunuzda, RSS'ye serileştiren bir serileştirici (WCF'de bir tane olduğunu düşünüyorum) bulacaksınız.
Haacked

8

Bunu Eran Kampf ve bir Scott Hanselman vidasından aldım (bağlantıyı unuttum), bu yüzden buradaki diğer yayınlardan sadece biraz farklı, ancak umarım yardımcı olur ve örnek rss beslemesi olarak kopyala yapıştır hazırdır.

Blogumdan

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

Ve Denetleyici Kodu ....

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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.