30

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

4

2 回答 2

28

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

这里,“操作”和“事务日期”被定义为 SOAP 头。

如果这些方法都没有帮助,那么您应该查看 WCF 消息检查器的概念,您可以将其编写为扩展。例如,它们允许您在客户端上的每次传出呼叫时将某些标头注入到消息中,并从服务器上的消息中检索这些标头以供您使用。

有关如何编写消息检查器以及如何将其包含在项目设置中的起点,请参阅此博客文章通过 WCF 行为处理自定义 SOAP 标头。

客户端IClientMessageInspector定义了两种方法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 信封中提取它们并使用它们。

更新:好的,您的客户端使用 .NET 2.0 并且使用 WCF - 好消息是,这应该仍然可以正常工作 - 请参阅此博客文章自定义 SOAP 标头:WCF 和 ASMX了解详细信息。您仍然可以使用服务器端的消息检查器来嗅探和提取 .NET 2.0 客户端发送的自定义标头。

于 2009-12-29T21:15:26.977 回答
3

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

            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 });
            }
于 2018-11-08T13:20:00.903 回答