如何在 wcf 中添加自定义肥皂标题?

Posted

技术标签:

【中文标题】如何在 wcf 中添加自定义肥皂标题?【英文标题】:How to add custom soap headers in wcf? 【发布时间】:2010-12-30 21:05:15 【问题描述】:

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

【问题讨论】:

用消息检查员的信息更新了我的答案 再次用关于 SOAP headersr 的 ASMX/WCF 互操作性信息更新了我的答案 感谢 marc_s,这看起来不错,我会试试看。 【参考方案1】:

查看 Codeplex 上的 WCF Extras - 这是一个简单的 WCF 扩展库,它提供了 - 除其他外 - 自定义 SOAP 标头。

另一种选择是在您的 WCF 服务中使用 WCF message contracts - 这也允许您轻松定义和设置 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 消息检查器的概念,您可以将其编写为扩展。它们允许您例如在客户端的每次传出呼叫时将某些标头注入到消息中,并从服务器上的消息中检索这些标头以供您使用。

请参阅此博客文章 Handling custom SOAP headers via WCF Behaviors,了解如何编写消息检查器以及如何将其包含在项目设置中。

客户端IClientMessageInspector定义了两个方法BeforeSendRequestAfterReceiveReply,而服务端IDispatchMessageInspector有相反的方法,即AfterReceiveRequestBeforeSendReply

有了这个,您可以为通过网络的每条消息添加标头(或选择性地仅添加到少数)。

这是来自 IClientMessageInspector 实现者的 sn-p,我们使用它自动将区域设置信息(语言和文化信息)从客户端传输到服务器 - 应该让您知道如何开始:

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 - 好消息是,这应该仍然可以正常工作 - 请参阅此博客文章Custom SOAP Headers: WCF and ASMX 了解详情。您仍然可以使用服务器端的消息检查器来嗅探和提取 .NET 2.0 客户端发送的自定义标头。

【讨论】:

感谢 marc_s,我尝试使用 WCF Extras,我在服务合同中添加了“XmlSerializerFormat”属性 WCF Extras 在访问服务时抛出错误。是否有任何其他可用的解决方案,如 WCF Extras?我可以在 ASMX 服务中添加 SoapHeader 时将 MessageContract 作为属性添加到每个方法吗?我的要求是我需要为每次调用 WCF 服务发送一些(同样的用户名和密码)数据。有没有办法实现这个? 是的 marc_s,看起来很棒。但在文章中提到的客户端应该是 .net 3.0 或更高版本..但在我的情况下,客户端是 .net 2.0 和 1.1。这个还可以实现吗?【参考方案2】:

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

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

【讨论】:

以上是关于如何在 wcf 中添加自定义肥皂标题?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 DataContractSerializer 从文件中反序列化 WCF 肥皂响应消息?

WCF 服务客户端:定制的肥皂信封未在线发送

HTTP 标头或 SOAP 标头中的 WCF 肥皂操作?

如何将自定义 WCF 协议通道添加到现有绑定

如何使用 WSDL 将用户代理添加到自动生成的肥皂客户端

休息与肥皂有啥区别[重复]