ASP.NET MVC의 RSS 피드


113

ASP.NET MVC에서 RSS 피드를 처리하는 것이 좋습니다. 타사 라이브러리를 사용하십니까? BCL에서 RSS 항목을 사용하십니까? XML을 렌더링하는 RSS보기를 만들고 있습니까? 아니면 완전히 다른 것이 있습니까?


RssToolkit을 사용하면 RSS 피드를 생성하기 위해 프로젝트에 .ashx 파일이 하나만 있으면됩니다. 그런 다음 URL을 친숙한 URL로 다시 작성할 수 있습니다. 이 접근 방식에서 MVC에 반대하는 것은 없다고 생각합니다.
Mahdi Taghizadeh

다음은 일반화 된 SyndicationAction 결과 클래스와 304 NotModified 조건부 가져 오기 필터를 사용하여 RssActionResult 아이디어를 조금 더 발전시킨 후속 게시물입니다. 58bits.com/blog/…
Blue Waters

원하는 경우 볼 수있는 RssResult를 작성했습니다. 요구 사항을 충족해야합니다. http://www.wduffy.co.uk/blog/rssresult-aspnet-mvc-rss-actionresult/
WDuffy

1
마지막 편집 후 18 개월을 기준으로이 질문을 업데이트하기 위해- '피드 관리 문제에 접근하는 방식을 변경하는 .net 및 mvc 모두에 대한 반복으로 인해 변경된 사항이 있습니까?'라는 질문이 합리적으로 보입니까? (다른 SO 스레드를 통한) 합의는 '근본적인 변경이 없습니다. 이것이 최상의 대안 세트로 남아 있습니다.'라는 것입니다.
justSteve 2011 년

ASP.NET MVC에 대한 잘못된 제안.
tugberk

답변:


64

내가 추천하는 것은 다음과 같습니다.

  1. 추상 기본 클래스 ActionResult를 상속하는 RssResult라는 클래스를 만듭니다.
  2. ExecuteResult 메서드를 재정의합니다.
  3. ExecuteResult에는 호출자가 전달한 ControllerContext가 있으며이를 통해 데이터 및 콘텐츠 유형을 가져올 수 있습니다.
  4. 콘텐츠 유형을 rss로 변경하면 데이터를 RSS로 직렬화하고 (자신의 코드 또는 다른 라이브러리를 사용하여) 응답에 쓸 수 있습니다.

  5. rss를 반환하려는 컨트롤러에서 작업을 만들고 반환 유형을 RssResult로 설정합니다. 반환하려는 항목을 기반으로 모델에서 데이터를 가져옵니다.

  6. 그런 다음이 작업에 대한 모든 요청은 선택한 데이터의 RSS를받습니다.

이것은 아마도 가장 빠르고 재사용 가능한 rss 반환 방법 일 것입니다. ASP.NET MVC의 요청에 대한 응답이 있습니다.


10
Hanselman은 FileResult에서 상속받은 유사한 솔루션 (동영상 : 약 41m 시작)을 보유하고 있습니다. 이렇게하면 클래스의 생성자를 호출 base("application/rss+xml")하고 3 단계와 4 단계를 피할 수 있습니다 . 그는 ExecuteResult를 재정의하지만 중요하지는 않습니다. 그는 또한 일반적으로-손으로 짠 코드를 많이 바로 가기와의 3.5 기능을 사용 SyndicateItem, SyndicateFeed하고 Rss20FeedFormatter.
patridge 2010-07-21

@Dale : 부분보기에 피드를 출력하고 싶을 때 응답에 쓸 수 있습니까? 감사.
Christian

1
이전 댓글에서 Hanselman의 비디오 링크를 업데이트했습니다 .
patridge

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"?>
Anthony Johnston

2
무슨 오버 헤드? 더 읽기 쉬운 방식으로 동일한 작업을 수행하기 위해 더 적은 코드를 작성하고 있다는 사실을 의미합니까?
Paul

12

또 다른 미친 방법은 RSS를 렌더링하기 위해 일반 .aspx보기를 사용하는 것입니다. 작업 방법에서 적절한 콘텐츠 유형을 설정하기 만하면됩니다. 이 접근 방식의 한 가지 이점은 렌더링되는 항목과 지리적 위치와 같은 사용자 지정 요소를 추가하는 방법을 쉽게 이해할 수 있다는 것입니다.

그런 다음 나열된 다른 접근 방식이 더 좋을 수 있습니다. 저는 사용하지 않았습니다. ;)


3
@Haacked : 세상은 템플릿 시스템에 의해 생성 된 유효하지 않은 RSS XML로 가득 차 있습니다. 엉망에 추가하지 마십시오! Ricky, HTML 인코딩! = XML 인코딩.
Brad Wilson

다음은 MSDN의 Html Encode 문서입니다.> 현재 구현 세부 사항으로 인해이 함수는 xmlEncode 함수로 사용할 수 있습니다. 현재이 함수에서 사용하는 모든 명명 된 엔터티는 xml 미리 정의 된 명명 된 엔터티이기도합니다. <> "& & lt; & gt; & quot; 및 & amp;로 인코딩됩니다. 다른 엔티티는 & # 160;과 같이 십진수 인코딩됩니다. http://msdn.microsoft.com/en-us/library/73z22y6h.aspx
Ricky

이런 식으로 XML이 유효한지 어떻게 확인할 수 있습니까? 보기 렌더링이 들어오는 웹 요청에서 분리되어 XML보기를 만들거나 done ruby ​​on rails와 같은 이메일 템플릿을 만들 수 있다면 좋을 것입니다.
Paco

보기 엔진을 사용하는 대신 ActionResult에서 파생되는 RssResult를 만들 수 있습니다. 객체를 JSON으로 직렬화하는 JsonResult로이를 수행합니다. 귀하의 경우 RSS로 직렬화되는 직렬 변환기 (WCF에 하나가 있다고 생각합니다)를 찾을 수 있습니다.
Haacked

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

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.