I successfully used System.ServiceModel.Syndication.SyndicationFeed
to add some Atom10 output from my ASP.NET 3.5 web site. It was my first production use of ServiceStack, and it all work fine.
My first attempt resulted in UTF-16 instead of UTF-8, which was ok for all browsers except IE. So I had to create XmlWriterResult
class to solve this. My solution works, but how should I have done?
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
is:
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; }
}
(Yes, I like delegates, I also do a lot of F#)
As this isn't a question with any clear answer I'd just tell you how I'd do it.
Assuming SyndicationFeed is a clean DTO / POCO you should just return that in your service:
This example uses ServiceStack's New API which is much nicer, you should try using it for future services.
This will allow you to get Content Negotiation in all of ServiceStack's registered Content-Types.
Registering a Custom Media Type
You could then register a Custom Media Type as seen in ServiceStack's Northwind v-card example:
Now the
rss+xml
format should appear in the/metadata
pages and ServiceStack will let you request the format in all the supported Content-Negotation modes, e.g:Accept: application/rss+xml
HTTP Header/rss+xml/syncreply/AsString
/route?format=rss+xml
to the QueryStringNote: you may need to url encode the '+' character