Tuesday, April 1, 2008

Serializing a data contract in WCF

The serialization in data contract to xml is little different in WCF model than traditional xml serialization. Here is 2 method I used in my custom WCF handler.
Imports System.Runtime.Serialization

Public Shared Function DeserializeObject(ByRef xmlizedString As String, ByRef objectType As Type) As Object
Dim memoryStream As New MemoryStream(StringToUTF8ByteArray(xmlizedString))
Dim dcs As New DataContractSerializer(objectType)
Return Convert.ChangeType(dcs.ReadObject(memoryStream), objectType)
End Function

Public Shared Function SerializeObject(ByRef xmlizableObject As Object, ByRef objectType As Type) As Object
Dim memoryStream As New MemoryStream()
Dim dcs As New DataContractSerializer(objectType)
dcs.WriteObject(memoryStream, xmlizableObject)
Return UTF8ByteArrayToString(memoryStream.ToArray())
End Function

sample code fragment to use the method :
dim student a new Student
dim studentData as string
studentData =SerializeObject(student , GetType(Student))

Tuesday, February 5, 2008

Method Overloading in WCF

In WCF, over loading a method involves a little “code around” to do.Lets go through the process sep by step.
First, let’s create a simple service contract with 2 overloaded function, something like the following,


_
Public
Interface IService1

_
Function
GetData(ByVal intParam As Integer) As String
_
Function
GetData(ByVal intParam As Integer, ByVal strParam As String) As String

End
Interface

Here 2 over load of “GetData” takes different number of parameter but returns same data type, “string”. It should have been worked according to general OOP concept . But OOPSI!!! you get the following error.

Server Error in '/FundTransferService' Application.


Cannot have two operations in the same contract with the same name, methods GetData and GetData in type IService1 violate this rule. You can change the name of one of the operations by changing the method name or by using the Name property of OperationContractAttribute.

We will add a “Name” property to the “OperationContract” attribute with different value,like the following.

_
Public
Interface IService1
"GetDataInt"
)> _
Function GetData(ByVal intParam As Integer) As String
"GetDataString")> _
Function GetData(ByVal intParam As Integer, ByVal strParam As String) As String
End Interface

Now if we add the service to client project the generated proxy class will have 2 different method with the name “GetDataInt” and “GetDataString”.

Dim sev1 As New Service1.Service1Client
Dim
resultInt As String = sev1.GetDataInt(5)
Dim
resultString As String = sev1.GetDataString(5, "Five")
sev1.Close()

So in the client side , the methodoverloading is still not fully implemented.
We will need to modify the client proxy class as well to fully implent the function overloading .
At the client side in the Reference.vb file, we have to add the same “Name” property to that OperationContract attribute in the Interface “IService1” and change the 2 method name to “GetData”.See below,

"System.ServiceModel", "3.0.0.0"), _
System.ServiceModel.ServiceContractAttribute(ConfigurationName:="Service1.IService1")>
Public
Interface IService1

Name:="GetDataInt", Action:="http://tempuri.org/IService1/GetDataInt", ReplyAction:="http://tempuri.org/IService1/GetDataIntResponse")> _
Function
GetData(ByVal intParam As Integer) As String

Name:="GetDataString", Action:="http://tempuri.org/IService1/GetDataString", ReplyAction:="http://tempuri.org/IService1/GetDataStringResponse")> Function GetData(ByVal intParam As Integer, ByVal strParam As String) As String
End
Interface

Now we will change the implimentation of that interface to make the 2 method of same method name. It is in the same Reference.VB class.

public Function GetData(ByVal intParam As Integer) As String Implements Service1.IService1.GetData
Return MyBase.Channel.GetData(intParam)

End Function

Public Function GetData(ByVal intParam As Integer, ByVal strParam As String) As String Implements Service1.IService1.GetData
Return MyBase.Channel.GetData(intParam, strParam)

End Function


Now we can write code in the client application in the following way,

Dim sev1 As New Service1.Service1Client
Dim resultInt As String = sev1.GetData(5)
Dim resultString As String = sev1.GetData(5, "Five")
sev1.Close()

Here “sev1.GetData” is taking different number of parameter and calling appropiate implementation accordingly.