4

放棄してServiceStackを使用して新しいサーバーコードを開発したいレガシーサーバーコードがあります。既存のクライアントは.Netで書き込まれません。クライアント側で.Netを使用する予定はありません。

クライアントとサーバー間のデータはXMLとJSONを使用して交換されています。現時点では、JSONは応答の戻り形式としてのみ使用されています(利用可能なサービスの一部のみ)。XML形式は、サーバーソリューションの最初のバージョンが数年前に作成されたときに定義されました。変更したくありません。

ServiceStackを使用して、過去に設計された形式にデータをシリアル化および逆シリアル化する新しいRESTful Webサービスを構築するにはどうすればよいですか(クライアントはC#/。Netで書き込まれないことに注意してください)。シリアル化と逆シリアル化の両方を制御する必要があります。DTOを使用しても、これらのオブジェクトをどのようにシリアル化/逆シリアル化するかを制御することは可能ですか?

4

1 に答える 1

5

要求/応答フィルターを介したカスタムロジックの追加

サービスが呼び出される前後にカスタムロジックを追加する方法については、要求フィルターと応答フィルターを参照してください。これらのフィルターを適用する必要があるサービスのみをマークできるため、要求/応答FilterAttributesを介してこれらのフィルターを追加することをお勧めします。

リクエストフィルターの問題は、リクエストDTOへのデシリアライズ後に発生するため、カスタムデシリアライズロジックを追加するには遅すぎます。これを回避するには、AppHostにカスタムリクエストバインダーを次のように登録します。

base.RegisterRequestBinder<MyRequest>(httpReq => ... requestDto);

これにより、IHttpRequestオブジェクトにアクセスでき、カスタムの逆シリアル化ロジックを自分で追加できます。もう1つのオプションは、ServiceStackに要求自体の逆シリアル化を試行せず、代わりにHttpRequest InputStreamを挿入して、要求を自分で逆シリアル化できるようにすることです。

public class Hello : IRequiresRequestStream {
    Stream RequestStream { get; set; }
}

これらの例は両方とも、ServiceStackのSerialization andDe-Serializationwikiページで説明されています。

独自のカスタムメディアタイプを登録する

強い型のDTOを返すことができるが、特定の要求の出力を変更できる別のオプションは、Northwind VCardカスタムメディアタイプの例で説明されているように、新しいカスタムメディアタイプを追加することで実行できます。

public static void Register(IAppHost appHost)
{
    appHost.ContentTypeFilters.Register( "text/x-vcard", SerializeToStream,  DeserializeFromStream);
}

...    

public static void SerializeToStream(IRequestContext requestContext, object response, Stream stream)
{
    var customerDetailsResponse = response as CustomerDetailsResponse;
    using (var sw = new StreamWriter(stream))
    {
        if (customerDetailsResponse != null)
        {
            WriteCustomer(sw, customerDetailsResponse.Customer);
        }
        var customers = response as CustomersResponse;
        if (customers != null)
        {
            customers.Customers.ForEach(x => WriteCustomer(sw, x));
        }
    }
}

これは、カスタムXML応答を別のコンテンツタイプ(たとえば、 application / v-xml )でマウントして、既存のXML形式/エンドポイントと競合しない場合に適したオプションです。HTTPクライアントの上でContentTypeを使用すると、 ?format = v-xmlまたはHTTPヘッダーを使用してこのカスタム実装を呼び出すことができます: Accept:application/v-xml

組み込みのXMLContentTypeをオーバーライドする場合でも可能ですが、サポートする必要のあるレガシー形式の1つでない場合は、SerializeStreamメソッドとDeserializeStreamメソッドの元のXmlSerializer実装にフォールバックすることをお勧めします。

ServiceStackをバイパスし、独自のカスタムIHttpHandlerを使用して実行します

もう1つのオプションは、ServiceStackを完全にバイパスし、代わりにAppHostのServiceStackの構成に登録して、独自のカスタムIHttpRequestハンドラーで要求を処理することです。

 SetConfig(new EndpointHostConfig { 
    RawHttpHandlers = {
      httpReq => return IsLegacyMatch(httpReq) ? new LegacyXmlHandler() : null 
    }
 });

null以外(つまり任意のハンドラー)を返すと、ServiceStackがバイパスされます。

于 2012-03-13T19:51:59.273 に答える