如何在wcf中添加自定义soap头?

如何在wcf中添加自定义soap头?,wcf,wcf-client,Wcf,Wcf Client,我是否可以在basicHttpBinding中的WCF传入/传出消息中添加自定义SOAP头,就像我们可以在ASMX web服务中添加自定义身份验证头一样?这些自定义SOAP头应该可以使用.net 2.0/1.1 web服务客户端(可通过WSDL.EXE工具访问)进行访问。查看on Codeplex-这是一个简单的WCF扩展库,它提供了自定义SOAP头等功能 [MessageContract] public class BankingTransaction { [MessageHeader]

我是否可以在basicHttpBinding中的WCF传入/传出消息中添加自定义SOAP头,就像我们可以在ASMX web服务中添加自定义身份验证头一样?这些自定义SOAP头应该可以使用.net 2.0/1.1 web服务客户端(可通过WSDL.EXE工具访问)进行访问。

查看on Codeplex-这是一个简单的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;
}
另一个选项是在您的WCF服务中使用—这也允许您轻松地定义和设置WCFSOAP头

[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消息检查器的概念,您可以将其编写为扩展。例如,它们允许您在客户端的每次传出呼叫中向消息中插入某些头,并从服务器上的消息中检索这些头供您使用

有关如何编写消息检查器以及如何将其包含在项目设置中的起点,请参阅本博客文章

客户端
IClientMessageInspector
定义了两种方法
BeforeSendRequest
AfterReceivePly
,而服务器端
IDispatchMessageInspector
具有相反的方法,即
AfterReceiveRequest
BeforeSendReply

通过这种方式,您可以为通过网络发送的每条消息添加标题(或者仅选择性地为少数消息添加标题)

下面是一段来自
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信封中提取它们并使用它们


更新:好的,您的客户在.NET 2.0上,没有使用WCF-好消息是,这应该仍然可以正常工作-有关详细信息,请参阅此博客文章。您仍然可以使用服务器端的message inspector嗅探和提取.NET 2.0客户端发送的自定义头。

此解决方案对我来说更简单:

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

感谢marc_s,我尝试使用WCF Extras,我在服务契约中添加了“XmlSerializerFormat”属性,WCF Extras在访问服务时抛出错误。是否有其他解决方案,如WCF Extras?在ASMX服务中添加SoapHeader时,是否可以将MessageContract作为属性添加到每个方法?我的要求是,每次调用WCF服务时,我都需要发送一些数据(比如用户名和密码)。有什么方法可以实现这个吗?是的,看起来很棒。但是在文章中提到的客户端应该是.NET3.0或更高版本的。但是在我的例子中,客户端是.NET2.0和1.1。是否仍有可能实现此功能?使用有关消息检查器的信息更新了我的答案使用有关SOAP头的ASMX/WCF互操作性的信息再次更新了我的答案谢谢marc_,这看起来不错,我将尝试一下。