我正在使用需要来自.NET 2网站的标头的WCF服务。如何以编程方式将标头添加到邮件中?

时间:2023-01-18 09:49:35

I have a WCF service that uses a custom instance provider (implements IInstanceProvider) for which the GetInstance method expects a message that contains a few headers, like this:

我有一个WCF服务,它使用自定义实例提供程序(实现IInstanceProvider),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);
    }

This service now needs to be called from a .NET 2 web application, so I added a basicHttpBinding endpoint to the WCF service and successfully added the web reference to that .NET 2 application which added an App_WebReferences folder with a MyService folder inside including the WSDL file and several .XSD files.

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

Just to clarify a little, that web application is written in VB.Net instead of C# and I'm not as familiar with VB.Net as I am with C#.

只是为了澄清一点,那个Web应用程序是用VB.Net而不是C#编写的,我对VB.Net的熟悉程度和我对C#的熟悉程度不同。

So, in the web application's code I wrote this:

所以,在Web应用程序的代码中我写了这样的:

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

This all works fine, the service receives the message to execute MyMethod, but, as expected, it returns an error message: "There is not a header with name Token and namespace urn:userinfo in the message."

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

With my other clients (C#, .NET 4.5), all I do in code when creating the client that will call the service is:

对于我的其他客户端(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"));

How can I do something similar in the .NET 2 application?

如何在.NET 2应用程序中执行类似的操作?

Thanks!

谢谢!


UPDATE:

更新:

I have now managed to pass a header to the service by creating a different class that inherits the class MyService.MyServiceHost and then overriding the method GetWriterForMessage, like this:

我现在设法通过创建一个继承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

And I created a new class called MySoapHeader that inherits from System.Web.Services.Protocols.SoapHeader and has a Token property.

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

Looking at the WCF service side, the message is coming with the header, but unfortunately the header name is the name of the class (MySoapHeader) and the namespace of the header is "http://tempuri.org", which is incorrect.

查看WCF服务端,消息随标头一起出现,但遗憾的是标题名称是类的名称(MySoapHeader),标题的名称空间是“http://tempuri.org”,这是不正确的。

How can I change that without having to name my class "Token" (which is very undesirable for a class name but it is the name of the header my service is expecting) and the header's namespace to "urn:userinfo"?

如何更改它,而不必命名我的类“令牌”(这是一个非常不希望的类名,但它是我的服务所期望的标题的名称)和标题的命名空间为“urn:userinfo”?

Thanks again!

再次感谢!

1 个解决方案

#1


1  

Ok, I managed to sort this one out.

好的,我设法排除了这个。

I created my own service class as I mentioned in the update, and created my own GetWriterForMessage method, like this:

我按照我在更新中提到的创建了自己的服务类,并创建了自己的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

I also had to create a class for my token header:

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

<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

Now I can run this code without any issues and the header is being passed down correctly:

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

Private myService As New MyExtendedServiceHost("my-token-here")
myService.Url = "http://myserver:1234/MyService"
myService.MyMethod()

#1


1  

Ok, I managed to sort this one out.

好的,我设法排除了这个。

I created my own service class as I mentioned in the update, and created my own GetWriterForMessage method, like this:

我按照我在更新中提到的创建了自己的服务类,并创建了自己的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

I also had to create a class for my token header:

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

<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

Now I can run this code without any issues and the header is being passed down correctly:

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

Private myService As New MyExtendedServiceHost("my-token-here")
myService.Url = "http://myserver:1234/MyService"
myService.MyMethod()