Elinizde mevcut bir web servisiniz var ve bu serviste bazı WebMethodlarınız SoapHeader kullanıyor(Yekilendirme,güvenlik,vs amaçlı).Bu servisinizi Silverlight uygulamanızda da kullanmak istiyorsunuz.Gayet güzel bir şekilde Silverlight projenizde Servis referanslarınızı oluşturdunuz ama Soapheader'in verileceği bir yer bulamadanız.
Çözümü System.ServiceModel.OperationContext ve System.Runtime.Serialization.XmlObjectSerializer kullanmak olacaktır.
Örneğin Aşağıdaki gibi bir web servisiniz olsun:
.....
Public Class OrnekServis
Inherits System.Web.Services.WebService
Public _Yetki As Yetki
Public Class Yetki : Inherits System.Web.Services.Protocols.SoapHeader
Public Sub New()
MyBase.New()
End Sub
Private _Ad As String
Public Property Ad() As String
Get
Return _Ad
End Get
Set(ByVal value As String)
_Ad = value
End Set
End Property
Private _Sifre As String
Public Property Sifre() As String
Get
Return _Sifre
End Get
Set(ByVal value As String)
_Sifre = value
End Set
End Property
Public Function Check() As Boolean
Return True
End Function
End Class
<SoapHeader("_Yetki", Direction:=SoapHeaderDirection.In)> _
<WebMethod(EnableSession:=True, Description:="Yeni bir dosya adi alir")> _
Public Function GetNewFileName() As String
If _Yetki is nothing Then return String.Empty
Dim g As String = Guid.NewGuid.ToString
Return g
End Function
End Class
Yukardaki web servisinde görüldüğü üzere GetNewFileName metodu Yetki SoapHeaderi beklentisi içerisinde.
Silverlight projemizde ise Visual Studio'nun oluşturduğu web servis referansı ise OrnekServisSoapClient isminde olsun.
.......
Public Class Yetki
Public Sub New()
MyBase.New()
End Sub
Private _Ad As String
Public Property Ad() As String
Get
Return _Ad
End Get
Set(ByVal value As String)
_Ad = value
End Set
End Property
Private _Sifre As String
Public Property Sifre() As String
Get
Return _Sifre
End Get
Set(ByVal value As String)
_Sifre = value
End Set
End Property
Public Function Check() As Boolean
Return True
End Function
End Class
..................
private _Service as OrnekServis.OrnekServisSoapClient
.......
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim b As New System.ServiceModel.BasicHttpBinding()
Dim ep As New System.ServiceModel.EndpointAddress("http://localhost:8888/Ornek.asmx")
_Service = New OrnekServis.OrnekServisSoapClient(b, ep)
End Sub
Şimdi
_Servisnesnemizdeki GetNewFileNameAsync metodunu çağırmadan önce SoapHeaderimiz ayarlamamız gerek.Bunuda aşağıdaki kod ile yapıyoruz.
Private Sub SetHeader()
If Not _Service Is Nothing Then
Dim mout As Object = System.ServiceModel.Channels.MessageHeader.CreateHeader("Yetki", "http://tempuri.org/BenimNameSpace", New Yetki With {.Ad = "TestUser", .Sifre = "1001"}, New YetkiSeri())
Dim ctx As New System.ServiceModel.OperationContext(_Service.InnerChannel)
ctx.OutgoingMessageHeaders.Clear()
ctx.OutgoingMessageHeaders.Add(mout)
System.ServiceModel.OperationContext.Current = ctx'Aktif Operation Context'imiz ayarlıyoruz
'Yada aşağıdaki metoduda kullanabiliriz
'Using temp As New System.ServiceModel.OperationContextScope(_Service.InnerChannel) 'System.ServiceModel.OperationContext.Current.OutgoingMessageHeaders.Add(mout)
'End Using
End If
End Sub
Burada dikkatimizi çeken
new YetkiSerisınıfı olacaktır.Bu sınıf gönderilen nesneyi istediğimiz gibi formatlayacaktır.
Public Class YetkiSeri
Inherits System.Runtime.Serialization.XmlObjectSerializer
Public Sub New()
MyBase.New()
End Sub
Public Overloads Overrides Function IsStartObject(ByVal reader As System.Xml.XmlDictionaryReader) As Boolean
Throw New NotImplementedException("!")
End Function
Public Overloads Overrides Function ReadObject(ByVal reader As System.Xml.XmlDictionaryReader, ByVal verifyObjectName As Boolean) As Object
Throw New NotImplementedException("!")
End Function
Public Overloads Overrides Sub WriteEndObject(ByVal writer As System.Xml.XmlDictionaryWriter)
Throw New NotImplementedException("!")
End Sub
Public Overloads Overrides Sub WriteObjectContent(ByVal writer As System.Xml.XmlDictionaryWriter, ByVal graph As Object)
If TypeOf graph Is Yetki Then
'Yetki snıfımız burada serialize olacaktır
Dim y As Yetki = DirectCast(graph, Yetki)
writer.WriteStartElement("Ad")
writer.WriteString(y.Ad)
writer.WriteEndElement()
writer.WriteStartElement("Sifre")
writer.WriteString(y.Sifre)
writer.WriteEndElement()
End If
End Sub
Public Overloads Overrides Sub WriteStartObject(ByVal writer As System.Xml.XmlDictionaryWriter, ByVal graph As Object)
Throw New NotImplementedException("!")
End Sub
End Class