如何在WCF中反序列化自定义SOAP标头?

我正在尝试通过WCF向所有SOAP请求添加自定义标头。 我发现这篇关于如何做到这一点的精彩文章 。 我的MessageHeader类看起来像这样:

 public class OperatorNameMessageHeader : MessageHeader { private string opName; public const string HeaderName = "OperatorNameMessageHeader"; public const string HeaderNamespace = "http://schemas.microsoft.com/scout"; public override string Name { get { return HeaderName; } } public override string Namespace { get { return HeaderNamespace; } } public string OperatorName { get { return opName; } set { opName = value; } } public OperatorNameMessageHeader() { } public OperatorNameMessageHeader(string operatorName) { opName = operatorName; } protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) { writer.WriteElementString("OperatorName", opName); } } 

文章没有说的一件事是如何读取服务器上的值。 根据这篇文章 ,您可以使用OperationContext.Current.IncomingMessageHeaders来读取这些标头。 当我在调试器下查看这些MessageHeaders ,我看到3个包含我的自定义标头。 因此,它肯定会出现在SOAP数据中。 但是,当我调用GetHeader

 OperatorNameMessageHeader test = msgHeaders.GetHeader(OperatorNameMessageHeader.HeaderName, OperatorNameMessageHeader.HeaderNamespace); 

然后test.OperatorName为null。 基本上,我只是回到一个空的OperatorNameMessageHeader对象,该对象尚未从SOAP中的数据反序列化。

我的下一步是运行WCF跟踪工具。 当我这样做时,我可以validation自定义标头确实是通过线路发送的:

  f9bef03b-4e7b-4e84-b327-5e79814d9933  Correct Operator Name  http://localhost:90/IRolesAndResourcesManager http://tempuri.org/IRolesAndResourcesManager/Authenticate  

所以,服务器数据,我无法得到它。 这个问题的解决方案是什么?

我有类似的问题。 我必须从标题中读取用户名和密码。 我找到了一个时间解决方案,我正在使用XmlDictionaryReader。 但是使用这个代码我只查找名称,我仍然可以改进它,但暂时工作。 我有它的VB,将类似于C#

  Dim username As String = "" Dim password As String = "" Dim usernameTokenId As String = "" Dim passwordType As String = "" For i As Integer = 0 To OperationContext.Current.IncomingMessageHeaders.Count - 1 Dim mhi As Channels.MessageHeaderInfo = OperationContext.Current.IncomingMessageHeaders.Item(i) Dim headers As Channels.MessageHeaders = OperationContext.Current.RequestContext.RequestMessage.Headers If mhi.Name.Equals("Security") Then Dim xr As XmlDictionaryReader = OperationContext.Current.IncomingMessageHeaders.GetReaderAtHeader(i) xr.MoveToContent() While xr.MoveToNextAttribute() Console.Write(" {0}='{1}'", xr.Name, xr.Value) End While Do Select Case xr.NodeType Case XmlNodeType.Element If xr.LocalName.Equals("Username") Then username = xr.ReadElementContentAsString() End If If xr.LocalName.Equals("Password") Then password = xr.ReadElementContentAsString() End If While xr.MoveToNextAttribute() If xr.LocalName.Equals("Id") Then usernameTokenId = xr.Value End If If xr.LocalName.Equals("Type") Then passwordType = xr.Value End If End While Case XmlNodeType.Attribute 'Case XmlNodeType.Text ' Console.Write(xr.Value) 'Case XmlNodeType.EndElement ' Console.Write("", xr.Name) End Select Loop While xr.Read() End If Dim name As String = mhi.Name Next