6

MVC4 (および/または WebAPI) を介して RSS フィードを作成する最良の方法を探しています。この投稿は、最も適切なhttp://www.strathweb.com/2012/04/rss-atom-mediatypeformatter-for-asp-net-webapi/のようです。しかし、これは WebAPI のリリース前に書かれたものです。Nuget を使用してすべてのパッケージを最新の状態にしましたが、プロジェクトのトスをビルドしようとしています。

Error   2   The type or namespace name 'FormatterContext' could not be found (are you missing a using directive or an assembly reference?)  G:\Code\MvcApplication-atomFormatter\MvcApplication-atomFormatter\SyndicationFeedFormatter.cs   38  129 MvcApplication_syndicationFeedFormatter

MediaTypeFormatter がベータ版から大幅に変更されたことを説明する多くの記事を見つけましたが、問題のコード スニペットに必要な調整の詳細を見つけました。

RSSFormatter の構造を示す更新されたリソースはありますか?

どうも

4

1 に答える 1

9

はい、ベータ版に対してそのチュートリアルを書きました。

以下は、RTM バージョンに更新されたコードです。

1 つのアドバイスとして、この例では、RSS/Atom フィードが構築される具体的なタイプ (この場合は私のUrlモデル) の単純な「ホワイトリスト」を使用することをお勧めします。理想的には、より複雑なシナリオでは、具象型ではなくインターフェイスに対してフォーマッタを設定し、そのインターフェイスを実装するために RSS として公開されるすべてのモデルを用意します。

お役に立てれば。

   public class SyndicationFeedFormatter : MediaTypeFormatter
    {
        private readonly string atom = "application/atom+xml";
        private readonly string rss = "application/rss+xml";

        public SyndicationFeedFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(atom));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(rss));
        }

        Func<Type, bool> SupportedType = (type) =>
        {
            if (type == typeof(Url) || type == typeof(IEnumerable<Url>))
                return true;
            else
                return false;
        };

        public override bool CanReadType(Type type)
        {
            return SupportedType(type);
        }

        public override bool CanWriteType(Type type)
        {
            return SupportedType(type);
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
        {
            return Task.Factory.StartNew(() =>
            {
                if (type == typeof(Url) || type == typeof(IEnumerable<Url>))
                    BuildSyndicationFeed(value, writeStream, content.Headers.ContentType.MediaType);
            });
        }

        private void BuildSyndicationFeed(object models, Stream stream, string contenttype)
        {
            List<SyndicationItem> items = new List<SyndicationItem>();
            var feed = new SyndicationFeed()
            {
                Title = new TextSyndicationContent("My Feed")
            };

            if (models is IEnumerable<Url>)
            {
                var enumerator = ((IEnumerable<Url>)models).GetEnumerator();
                while (enumerator.MoveNext())
                {
                    items.Add(BuildSyndicationItem(enumerator.Current));
                }
            }
            else
            {
                items.Add(BuildSyndicationItem((Url)models));
            }

            feed.Items = items;

            using (XmlWriter writer = XmlWriter.Create(stream))
            {
                if (string.Equals(contenttype, atom))
                {
                    Atom10FeedFormatter atomformatter = new Atom10FeedFormatter(feed);
                    atomformatter.WriteTo(writer);
                }
                else
                {
                    Rss20FeedFormatter rssformatter = new Rss20FeedFormatter(feed);
                    rssformatter.WriteTo(writer);
                }
            }
        }

        private SyndicationItem BuildSyndicationItem(Url u)
        {
            var item = new SyndicationItem()
            {
                Title = new TextSyndicationContent(u.Title),
                BaseUri = new Uri(u.Address),
                LastUpdatedTime = u.CreatedAt,
                Content = new TextSyndicationContent(u.Description)
            };
            item.Authors.Add(new SyndicationPerson() { Name = u.CreatedBy });
            return item;
        }
    }
于 2012-09-15T14:34:34.667 に答える