2

System.ServiceModel.Syndication.SyndicationFeedASP.NET 3.5 Web サイトから Atom10 出力を追加することに成功しました。ServiceStack を実際に使用するのはこれが初めてで、すべて正常に動作します。

私の最初の試行では、UTF-8 ではなく UTF-16 になりました。これは、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# もよくします)

4

1 に答える 1

2

これは明確な答えのある質問ではないので、私がそれをどのように行うかをお話しします。

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表示され、/metadataServiceStackでサポートされているすべてのコンテンツネゴシエーションモードでフォーマットをリクエストできるようになります。例:

  • Accept: application/rss+xmlHTTPヘッダー
  • 事前定義されたルートを使用します。例:/rss+xml/syncreply/AsString
  • または/route?format=rss+xml、QueryStringに追加します

注:「+」文字をURLエンコードする必要がある場合があります

于 2012-10-23T02:41:20.050 に答える