4

MIME マルチパート結果をバイナリ データ (実際には PDF ファイル) で返す SOAP サービスに WCF クライアントを作成しています。カスタム メッセージ エンコーダーを使用します。

リクエストをシングルパート形式にしてもサービスは問題ないようで、結果を返すことができます。私が見ることができる結果には2つの問題があります。

  • マルチパート メッセージの最初の部分のみを返すようです。
  • 返されたデータをカスタム エンコーダーでデコードできません。

MTOM バインディングを利用しようとしましたが、それは要求を台無しにします。content-type に「boundary」パラメータを追加できないため、サーバーはリクエストを理解できません。

私が欲しいのは基本的なテキストの SOAP 要求だと思いますが、応答は MTOM スタイルでデコードされます。ただし、それを設定する方法がわかりません。

私が見つけた最も近い解決策はこれです: http://blogs.msdn.com/b/carlosfigueira/archive/2011/02/16/using-mtom-in-a-wcf-custom-encoder.aspx

しかし、それは私のプロジェクトにとって非常に侵略的な変更のようです。

4

1 に答える 1

5

私はこれを理解しました。まず第一に、MTOMエンコーダーを使用してマルチパートメッセージの最初の部分しか取得していないと言ったとき、私は間違っていました。私はすべてを手に入れていました。私はデバッガーでそれを見ていました、そして、底はデバッグビューアでクリップされたに違いありません。マルチパートメッセージを手動で見て解読する私の経験不足にチョークで書きます。

2つ目のポイントとして、Content-Typeがマルチパート/関連であり、すべてが正常に機能している場合は、MTOMエンコーダーを使用するだけで済みました。上記の参照記事を読むと、メッセージがマルチパートテキストか通常のテキストかを動的に検出し、それに基づいて適切なエンコーダーを選択することがすべてです。基本的に、これはテキストエンコーダーとMTOMエンコーダーの両方が組み込まれたカスタムエンコーダーであり、着信メッセージのコンテンツタイプに基づいて前後に切り替わります。

私たちのプロジェクトでは、応答メッセージがメインプログラムロジックに渡される前に、応答メッセージの後処理が必要です。したがって、着信SOAPコンテンツをXML文字列として取得し、それに対してXML操作を行います。

これは、この記事で推奨されているソリューションからのわずかな逸脱です。この記事のソリューションで必要なのは、適切なエンコーダーを使用してメッセージをSystem.ServiceModel.Channels.Messageに読み取り、それを返すことだけです。私たちのソリューションでは、このプロセスを中断して後処理を行う必要があります。

これを行うには、カスタムエンコーダーに以下を実装します。

public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
    //First, get the incoming message as a byte array
    var messageData = new byte[buffer.Count];
    Array.Copy(buffer.Array, buffer.Offset, messageData, 0, messageData.Length);
    bufferManager.ReturnBuffer(buffer.Array);
    //Now convert it into a string for post-processing.  Look at the content-type to determine which encoder to use.
    string stringResult;
    if (contentType != null && contentType.Contains("multipart/related"))
    {
        Message unprocessedMessageResult = this.mtomEncoder.ReadMessage(buffer, bufferManager, contentType);
        stringResult = unprocessedMessageResult.ToString();
    }
    else {
        //If it's not a multi-part message, the byte array already has the complete content, and it simply needs to be converted to a string
        stringResult = Encoding.UTF8.GetString(messageData);
    }
    Message processedMessageResult = functionToDoPostProccessing(stringResult);
    return processedMessageResult;
}
于 2012-08-17T16:34:24.517 に答える