web-dev-qa-db-ja.com

WCFでカスタムSOAPヘッダーを追加する方法

ASMX Webサービスにカスタム認証ヘッダーを追加できるように、basicHttpBindingのWCF受信/送信メッセージにカスタムSOAPヘッダーを追加できますか?これらのカスタムSOAPヘッダーは.net 2.0/1.1 Webサービスクライアント(WSDL.EXEツールからアクセス可能)を使用してアクセスできる。

26
nRk

Codeplexの WCF Extras を確認してください。これはWCFの簡単な拡張ライブラリであり、とりわけ-カスタムSOAP=ヘッダーを提供します。

別のオプションは、WCFサービスで WCFメッセージコントラクト を使用することです。これにより、WCF SOAPヘッダーを定義および設定することも簡単にできます。

[MessageContract]
public class BankingTransaction
{
  [MessageHeader]
  public Operation operation;
  [MessageHeader] 
  public DateTime transactionDate;

  [MessageBodyMember] 
  private Account sourceAccount;
  [MessageBodyMember] 
  private Account targetAccount;
  [MessageBodyMember] 
  public int amount;
}

ここでは、「操作」と「transactionDate」はSOAPヘッダーとして定義されています。

これらの方法のいずれも役に立たない場合は、拡張機能として作成できるWCFメッセージインスペクターの概念を確認する必要があります。たとえば、次のことができます。クライアントのすべての発信呼び出しで特定のヘッダーをメッセージに挿入し、サーバーでメッセージからそれらを取得して使用します。

メッセージインスペクターを作成する方法、およびプロジェクトセットアップにメッセージインスペクターを含める方法については、このブログ投稿 Handling custom SOAP headers via WCF Behaviors を参照してください。

クライアント側のIClientMessageInspectorは、2つのメソッドBeforeSendRequestAfterReceiveReplyを定義しますが、サーバー側のIDispatchMessageInspectorは、反対のメソッド、つまりAfterReceiveRequestBeforeSendReplyを備えています。

これにより、回線を通過するすべてのメッセージにヘッダーを追加することができます(または選択的に少数にのみ)。

以下は、クライアントからサーバーにロケール情報(言語およびカルチャ情報)を自動的に送信するために使用するIClientMessageInspectorインプリメンターからのスニペットです。開始方法のアイデアが得られるはずです。

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
    International intlHeader = new International();
    intlHeader.Locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;

    MessageHeader header = MessageHeader.CreateHeader(WSI18N.ElementNames.International, WSI18N.NamespaceURI, intlHeader);
    request.Headers.Add(header);

    return null;
}

サーバー側では、これらのヘッダーの存在を確認し、存在する場合はSOAPエンベロープから抽出して使用します。

UPDATE:さて、クライアントは.NET 2.0上にあり、ではありませんWCFの使用-良いニュースですが、これは問題なく機能します-このブログ投稿を参照してください Custom SOAP Headers:WCF and ASMX 詳細については、 .NET 2.0クライアントから送信されているカスタムヘッダーを傍受して抽出するための、サーバー側のメッセージインスペクター。

26
marc_s

このソリューションは私にとってより簡単でした:

            var client = "Your Service Client"; 
            using (var scope = new OperationContextScope(client.InnerChannel))
            {
                System.Xml.XmlDocument document = new XmlDocument();
                XmlElement element = document.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

                XmlElement newChild = null;
                newChild = document.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                newChild.InnerText = "finance";
                element.AppendChild(newChild);

                newChild = document.CreateElement("wsse", "CorporationCode", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                newChild.InnerText = "387";
                element.AppendChild(newChild);

                MessageHeader messageHeader = MessageHeader.CreateHeader("UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", element, false);

                OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);

                var result = client.GetCorporations(new CorporationType { pageNo = 1 });
            }
1
B.Tekkan