如何使用ServiceStack使用SyndicationFeed来改善RSS/Atom的解决方案



我成功使用System.ServiceModel.Syndication.SyndicationFeed从我的ASP.NET 3.5网站添加了一些ATOM10输出。这是我第一次生产ServiceStack,这一切都很好。

我的第一次尝试导致UTF-16而不是UTF-8,这对于除IE以外的所有浏览器都是可以的。因此,我必须创建XmlWriterResult类来解决这个问题。我的解决方案有效,但是我应该怎么做?

public class AsStringService : IService<AsString>
{
    public object Execute(AsString request)
    {
        SyndicationFeed feed = new SyndicationFeed("Test Feed " + request.Name, "This is a test feed", new Uri("http://Contoso/testfeed"), "TestFeedID", DateTime.Now);
        SyndicationItem item = new SyndicationItem("Test Item", "This is the content for Test Item", new Uri("http://localhost/ItemOne"), "TestItemID", DateTime.Now);
        List<SyndicationItem> items = new List<SyndicationItem>();
        items.Add(item);
        feed.Items = items;
        Atom10FeedFormatter atomFormatter = new Atom10FeedFormatter(feed);
        return new XmlWriterResult(xmlWriter => atomFormatter.WriteTo(xmlWriter));
    }
}

XmlWriterResult是:

public delegate void XmlWriterDelegate(XmlWriter xmlWriter);
/// <summary>
/// From https://groups.google.com/forum/?fromgroups=#!topic/servicestack/1U02g7kViRs
/// </summary>
public class XmlWriterResult : IDisposable, IStreamWriter, IHasOptions
{
     private readonly XmlWriterDelegate _writesToXmlWriter;
     public XmlWriterResult(XmlWriterDelegate writesToXmlWriter)
     {
         _writesToXmlWriter = writesToXmlWriter;
         this.Options = new Dictionary<string, string> {
              { HttpHeaders.ContentType, "text/xml" }
         };
     }
     public void Dispose()
     {
     }
     public void WriteTo(Stream responseStream)
     {
         using (XmlWriter xmlWriter = XmlWriter.Create(responseStream))
         {
             _writesToXmlWriter(xmlWriter);
         }
     }
     public IDictionary<string, string> Options { get; set; }
}

(是的,我喜欢代表,我也做很多F#)

,因为这不是一个明确答案的问题,我只是告诉你我如何做。

假设 SyndicationFeed 是一个干净的DTO/POCO,您应该在服务中返回该:

public class AsStringService : IService
{
    public object Any(AsString request)
    {
        SyndicationFeed feed = new SyndicationFeed("Test Feed " + request.Name, 
           "This is a test feed", new Uri("http://Contoso/testfeed"), 
           "TestFeedID", DateTime.Now);
        SyndicationItem item = new SyndicationItem("Test Item", 
           "This is the content for Test Item", 
            new Uri("http://localhost/ItemOne"), 
           "TestItemID", DateTime.Now);
        List<SyndicationItem> items = new List<SyndicationItem>();
        items.Add(item);
        feed.Items = items;
        return feed;
    }
}

此示例使用ServiceStack的新API,它应该尝试使用它,您应该尝试将其用于将来的服务。

这将使您能够在Servicestack的所有注册内容类型中获得内容谈判。

注册自定义媒体类型

您可以注册ServiceStack的Northwind V-Card示例中看到的自定义媒体类型:

private const string AtomContentType = "application/rss+xml";
public static void Register(IAppHost appHost)
{
    appHost.ContentTypeFilters.Register(AtomContentType, SerializeToStream, 
        DeserializeFromStream);
}
public static void SerializeToStream(IRequestContext requestContext, 
    object response, Stream stream)
{
    var syndicationFeed = response as SyndicationFeed;
        if (SyndicationFeed == null) return;
    using (XmlWriter xmlWriter = XmlWriter.Create(stream))
    {
            Atom10FeedFormatter atomFormatter = new Atom10FeedFormatter(feed);
            atomFormatter.WriteTo(xmlWriter);
    }
}
public static object DeserializeFromStream(Type type, Stream stream)
{
    throw new NotImplementedException();
}

现在,rss+xml格式应显示在/metadata页面中,ServiceStack将让您在所有受支持的内容结论模式中请求该格式,例如:

  • Accept: application/rss+xml HTTP标头
  • 使用预定义的路线,例如:/rss+xml/syncreply/AsString
  • 或将/route?format=rss+xml附加到QUERYSTRING

注意:您可能需要编码" "字符

最新更新