web-dev-qa-db-fra.com

Comment ajouter des en-têtes de savon personnalisés dans wcf?

Puis-je ajouter un en-tête personnalisé SOAP dans les messages WCF entrants/sortants dans basicHttpBinding, comme nous pouvons ajouter un en-tête d'authentification personnalisé dans les services Web ASMX? Ces en-têtes personnalisés SOAP devraient être accessible à l'aide des clients du service Web .net 2.0/1.1 (accessible par l'outil WSDL.EXE).

26
nRk

Consultez le WCF Extras sur Codeplex - c'est une bibliothèque d'extension facile pour WCF qui propose - entre autres - des en-têtes personnalisés SOAP.

Une autre option consiste à utiliser contrats de message WCF dans votre service WCF - cela vous permet également de définir et de définir facilement les en-têtes 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;
}

Ici, "operation" et "transactionDate" sont définis comme SOAP headers.

Si aucune de ces méthodes ne vous aide, vous devriez vérifier le concept des inspecteurs de messages WCF que vous pouvez écrire en tant qu'extensions. Ils vous permettent par exemple injectez certains en-têtes dans le message à chaque appel sortant sur le client, et récupérez ceux du message sur le serveur pour votre usage.

Voir cet article de blog Gestion des en-têtes personnalisés SOAP en-têtes via les comportements WCF pour un point de départ sur la façon d'écrire un inspecteur de message et de l'inclure dans la configuration de votre projet.

Le côté client IClientMessageInspector définit deux méthodes BeforeSendRequest et AfterReceiveReply tandis que le côté serveur IDispatchMessageInspector a les méthodes opposées, à savoir AfterReceiveRequest et BeforeSendReply.

Avec cela, vous pouvez ajouter des en-têtes à chaque message traversant le fil (ou sélectivement seulement à quelques-uns).

Voici un extrait d'un implémenteur IClientMessageInspector que nous utilisons pour transmettre automatiquement les informations locales (informations sur la langue et la culture) des clients au serveur - devrait vous donner une idée de la façon de commencer:

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;
}

Côté serveur, vous devriez alors vérifier la présence de ces en-têtes, et s'ils sont présents, les extraire de l'enveloppe SOAP et les utiliser.

MISE À JOUR: d'accord, vous êtes des clients sur .NET 2.0 et pas en utilisant WCF - bonne nouvelle, cela devrait toujours fonctionner correctement - voir cet article de blog Custom SOAP Headers: WCF and ASMX pour plus de détails. Vous pouvez toujours utiliser le inspecteur de messages côté serveur pour détecter et extraire les en-têtes personnalisés envoyés par vos clients .NET 2.0.

26
marc_s

Cette solution était plus simple pour moi:

            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