我有一个使用自定义实例提供程序(实现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应用程序调用此服务,因此我将一个basicHttpBinding端点添加到WCF服务,并成功将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和namespace 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服务端,消息随标头一起出现,但遗憾的是标题名称是类的名称(MySoapHeader),标题的名称空间是“http://tempuri.org”,这是不正确的
如何更改它而不必命名我的类“Token”(这对于类名称来说是非常不受欢迎的,但它是我的服务所期望的标题的名称)以及标题的名称空间为“urn:userinfo”?
再次感谢!
答案 0 :(得分:1)
好的,我设法排除了这个。
我按照我在更新中提到的创建了自己的服务类,并创建了自己的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()