我可以在 basicHttpBinding 的 WCF 传入/传出消息中添加自定义 SOAP 标头,就像我们可以在 ASMX Web 服务中添加自定义身份验证标头一样?这些自定义 SOAP 标头应该可以使用 .net 2.0/1.1 Web 服务客户端访问(可通过 WSDL.EXE 工具访问)。
2 回答
查看 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
定义了两种方法BeforeSendRequest
,AfterReceiveReply
而服务器端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 - 好消息是,这应该仍然可以正常工作 - 请参阅此博客文章自定义 SOAP 标头:WCF 和 ASMX了解详细信息。您仍然可以使用服务器端的消息检查器来嗅探和提取 .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 });
}