1

我有一个使用自定义实例提供程序(实现 IInstanceProvider)的 WCF 服务,GetInstance 方法需要一个包含一些标头的消息,如下所示:

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        string token = null;

        if (message != null)
        {
            token = message.Headers.GetHeader<string>("Token", "urn:userinfo");
        }

        Bootstrapper bootstrapper = new Bootstrapper();
        bootstrapper.InitialiseSession(token);

        return new MyServiceHost(bootstrapper.ServiceModel);
    }

现在需要从 .NET 2 Web 应用程序调用此服务,因此我向 WCF 服务添加了一个 basicHttpBinding 端点,并成功地将 Web 引用添加到该 .NET 2 应用程序,该应用程序添加了一个 App_WebReferences 文件夹,其中包含一个 MyService 文件夹,包括 WSDL文件和几个 .XSD 文件。

澄清一下,该 Web 应用程序是用 VB.Net 而不是 C# 编写的,而且我对 VB.Net 的熟悉程度不如我对 C# 的熟悉程度。

因此,在 Web 应用程序的代码中,我这样写:

    Private myService As MyService.MyServiceHost
    myService.Url = "http://myserver:1234/MyService"
    myService.MyMethod()

这一切正常,服务接收到执行 MyMethod 的消息,但是,正如预期的那样,它返回一条错误消息:“消息中没有名称为 Token 和命名空间 urn:userinfo 的标头。”

对于我的其他客户端(C#、.NET 4.5),在创建将调用该服务的客户端时,我在代码中所做的一切是:

    MessageHeader<string> headerToken;
    OperationContext.Current = new OperationContext((IContextChannel)serviceClient);
    headerToken = new MessageHeader<string>("insert-token-here");
    OperationContext.Current.OutgoingMessageHeaders.Add(headerToken.GetUntypedHeader("Token", "urn:userinfo"));

如何在 .NET 2 应用程序中做类似的事情?

谢谢!


更新:

我现在设法通过创建一个继承类 MyService.MyServiceHost 的不同类,然后覆盖方法 GetWriterForMessage,将标头传递给服务,如下所示:

    Protected Overrides Function GetWriterForMessage(ByVal message As System.Web.Services.Protocols.SoapClientMessage, ByVal bufferSize As Integer) As System.Xml.XmlWriter
        Dim myWriterForMessage As System.Xml.XmlWriter

        Dim myHeader As MySoapHeader
        myHeader = New MySoapHeader()
        myHeader.Token = "myToken"

        message.Headers.Add(myHeader)
        myWriterForMessage = MyBase.GetWriterForMessage(message, bufferSize)

        Return myWriterForMessage
    End Function
End Class

我创建了一个名为 MySoapHeader 的新类,它继承自 System.Web.Services.Protocols.SoapHeader 并具有 Token 属性。

看WCF服务端,消息是带着header来的,可惜header名字是类名(MySoapHeader),header的命名空间是“ http://tempuri.org ”,不正确。

如何更改它而不必将我的类命名为“Token”(这对于类名来说是非常不可取的,但它是我的服务所期望的标题的名称)并将标题的命名空间命名为“urn:userinfo”?

再次感谢!

4

1 回答 1

2

好的,我设法解决了这个问题。

如更新中所述,我创建了自己的服务类,并创建了自己的 GetWriterForMessage 方法,如下所示:

Partial Public Class MyExtendedServiceHost
    Inherits MyService.MyServiceHost

    Private _token As String

    Public Sub New(ByVal token As String)
        _token = token
    End Sub

    Protected Overrides Function GetWriterForMessage(ByVal message As System.Web.Services.Protocols.SoapClientMessage, ByVal bufferSize As Integer) As System.Xml.XmlWriter
        Dim myWriterForMessage As System.Xml.XmlWriter

        Dim myTokenHeader As TokenSoapHeader
        myTokenHeader = New TokenSoapHeader()
        myTokenHeader.Value = _token

        message.Headers.Add(myTokenHeader)
        myWriterForMessage = MyBase.GetWriterForMessage(message, bufferSize)

        Return myWriterForMessage
    End Function
End Class

我还必须为我的令牌头创建一个类:

<XmlRoot(Namespace:="urn:userinfo", ElementName:="Token", DataType:="string", IsNullable:=False)> _
Public Class TokenSoapHeader
    Inherits System.Web.Services.Protocols.SoapHeader

    <XmlText()> _
    Public Value As String
End Class

现在我可以毫无问题地运行此代码,并且标头已正确传递:

Private myService As New MyExtendedServiceHost("my-token-here")
myService.Url = "http://myserver:1234/MyService"
myService.MyMethod()
于 2013-04-30T15:07:45.453 回答